# Copyright: (c) 2025, Luca Bilke <luca@bil.ke>
# MIT License (see LICENSE)

from __future__ import annotations

from copy import deepcopy
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from types import ModuleType

from ansible_collections.snailed.ez_compose.plugins.module_utils import (
    label,
    service,
)


def get_modules(parent_module: ModuleType) -> list[tuple[str, ModuleType]]:
    return [
        (name, getattr(parent_module, name)) for name in parent_module.__all__ if name != "common"
    ]


def get_module_options(
    module: ModuleType,
    base_args: dict[str, Any] | None = None,
) -> dict[str, Any]:
    if not base_args:
        base_args = {}

    if force_args := getattr(module, "FORCE_ARGS", None):
        return force_args

    if extra_args := getattr(module, "EXTRA_ARGS", None):
        return {
            **base_args,
            **extra_args,
        }

    return base_args


def label_argument_spec() -> dict[str, Any]:
    label_args: dict[str, Any] = {
        "type": "dict",
        "options": {},
    }

    for module_name, module in get_modules(label):
        label_args["options"][module_name] = {
            "type": "dict",
            "options": get_module_options(module, label.common.BASE_ARGS),
        }

    return label_args


def service_argument_spec() -> dict[str, Any]:
    service_args: dict[str, Any] = {
        "type": "dict",
        "options": {},
        "required": True,
    }

    for module_name, module in get_modules(service):
        service_args["options"][module_name] = {
            "type": "list",
            "elements": "dict",
            "options": get_module_options(module, service.common.BASE_ARGS),
        }

    return service_args


def settings_spec() -> dict[str, Any]:
    settings: dict[str, Any] = {
        "type": "dict",
        "options": {
            "default_definition": {"type": "dict"},
            "service_default_args": {"type": "dict", "options": {}},
            "label_default_args": {"type": "dict", "options": {}},
            "service_default_definitions": {"type": "dict", "options": {}},
        },
    }

    for module_name, module in get_modules(service):
        settings["options"]["service_default_definitions"]["options"][module_name] = {
            "type": "dict",
        }

        service_args: dict[str, Any] = deepcopy(get_module_options(module))

        for arg in service_args.values():
            arg.pop("required", None)
            arg.pop("default", None)

        settings["options"]["service_default_args"]["options"][module_name] = {
            "type": "dict",
            "options": service_args,
        }

    for module_name, module in get_modules(label):
        label_args: dict[str, Any] = deepcopy(get_module_options(module))

        for arg in label_args.values():
            arg.pop("required", None)
            arg.pop("default", None)

        settings["options"]["label_default_args"]["options"][module_name] = {
            "type": "dict",
            "options": label_args,
        }

    return settings