"""Multi-cloud module registry.

Discovers module directories for each configured cloud and parses them
into an in-memory index keyed by (cloud, module_name).
"""

from __future__ import annotations

import os
from pathlib import Path

from tf_mcp.dependencies import get_module_layers
from tf_mcp.models import ModuleInfo
from tf_mcp.parser import parse_module

# Default sibling-repo layout:
#   ~/repos/aws-tf/modules/
#   ~/repos/azure-tf/modules/
#   ~/repos/gcp-tf/modules/
#   ~/repos/tf-mcp-server/   <-- this repo

DEFAULT_CLOUD_REPOS = {
    "aws": "aws-tf",
    "azure": "azure-tf",
    "gcp": "gcp-tf",
}


def _resolve_modules_dir(cloud: str) -> Path | None:
    """Find the modules/ directory for a cloud.

    Priority:
    1. TF_MODULES_{CLOUD}_DIR env var (e.g. TF_MODULES_AWS_DIR)
    2. Sibling repo relative to this package's repo root
    """
    env_key = f"TF_MODULES_{cloud.upper()}_DIR"
    env_dir = os.environ.get(env_key)
    if env_dir:
        p = Path(env_dir)
        if p.is_dir():
            return p
        return None

    # Walk up from this file to find the repo root, then look for sibling
    repo_name = DEFAULT_CLOUD_REPOS.get(cloud)
    if not repo_name:
        return None

    current = Path(__file__).resolve().parent
    for _ in range(10):
        sibling = current.parent / repo_name / "modules"
        if sibling.is_dir():
            return sibling
        current = current.parent

    return None


class ModuleRegistry:
    """In-memory registry of parsed Terraform modules across all clouds."""

    def __init__(self) -> None:
        self._modules: dict[str, dict[str, ModuleInfo]] = {}
        self._load_all()

    def _load_all(self) -> None:
        for cloud in ("aws", "azure", "gcp"):
            modules_dir = _resolve_modules_dir(cloud)
            if not modules_dir:
                continue

            layers = get_module_layers(cloud)
            cloud_modules: dict[str, ModuleInfo] = {}

            if layers:
                # Load only known modules from the cloud metadata
                for module_name in layers:
                    module_dir = modules_dir / module_name
                    if module_dir.is_dir():
                        cloud_modules[module_name] = parse_module(module_dir, cloud=cloud)
            else:
                # No metadata yet — discover all subdirectories with a main.tf
                for child in sorted(modules_dir.iterdir()):
                    if child.is_dir() and (child / "main.tf").exists():
                        cloud_modules[child.name] = parse_module(child, cloud=cloud)

            if cloud_modules:
                self._modules[cloud] = cloud_modules

    @property
    def clouds(self) -> list[str]:
        return sorted(self._modules.keys())

    def get(self, cloud: str, name: str) -> ModuleInfo | None:
        return self._modules.get(cloud, {}).get(name)

    def list_names(self, cloud: str) -> list[str]:
        return sorted(self._modules.get(cloud, {}).keys())

    def list_all(self) -> list[tuple[str, str]]:
        """Return all (cloud, module_name) pairs."""
        result: list[tuple[str, str]] = []
        for cloud in self.clouds:
            for name in self.list_names(cloud):
                result.append((cloud, name))
        return result
