"""Go mirror failover support."""

from pathlib import Path
from loguru import logger

from multi_lang_build.compiler.base import BuildResult
from multi_lang_build.mirror.config import (
    MIRROR_CONFIGS,
    get_go_mirror_with_fallback,
    apply_mirror_environment,
)


class GoMirrorFailover:
    """Handle Go mirror failover logic."""

    def __init__(self, configured_mirror: str | None = None):
        """Initialize mirror failover handler.

        Args:
            configured_mirror: User-configured mirror key (if any).
                              If None, will use failover mode.
        """
        self.configured_mirror = configured_mirror

    def get_mirror_info(self, mirror_key: str) -> tuple[str, str]:
        """Get mirror name and URL.

        Args:
            mirror_key: Mirror configuration key

        Returns:
            Tuple of (name, url)
        """
        config = MIRROR_CONFIGS.get(mirror_key, {})
        return config.get("name", mirror_key), config.get("url", "")

    def apply_mirror(self, mirror_key: str, environment: dict[str, str]) -> dict[str, str]:
        """Apply mirror environment variables.

        Args:
            mirror_key: Mirror configuration key
            environment: Base environment variables

        Returns:
            Updated environment with mirror variables
        """
        config_key = self.configured_mirror or mirror_key
        return apply_mirror_environment(config_key, environment)

    def try_build_with_fallback(
        self,
        command: list[str],
        source_dir: Path,
        output_dir: Path,
        environment: dict[str, str],
        stream_output: bool,
        run_build_func,
    ) -> BuildResult:
        """Try build command with mirror failover.

        Tries mirrors in order: goproxy.io → goproxy.cn → goproxy.vip.cn
        Only switches to next mirror on failure.

        Args:
            command: Build command to execute
            source_dir: Source directory for the build
            output_dir: Output directory for build artifacts
            environment: Environment variables
            stream_output: Whether to stream output in real-time
            run_build_func: Function to execute the build

        Returns:
            BuildResult with success status and output information.
        """
        # If user configured a specific mirror, use it without failover
        if self.configured_mirror:
            mirror_name, _ = self.get_mirror_info(self.configured_mirror)
            logger.info(f"🔗 使用代理: {mirror_name}")
            env = self.apply_mirror(self.configured_mirror, environment)
            return run_build_func(command, source_dir, output_dir, env, stream_output)

        # Use failover mode
        mirror_keys = get_go_mirror_with_fallback(failover=True)
        last_result: BuildResult | None = None

        for i, mirror_key in enumerate(mirror_keys):
            env = environment.copy()
            mirror_name, mirror_url = self.get_mirror_info(mirror_key)
            logger.info(f"🔗 使用代理: {mirror_name} ({mirror_url})")

            env = self.apply_mirror(mirror_key, env)

            result = run_build_func(command, source_dir, output_dir, env, stream_output)
            last_result = result

            if result["success"]:
                return result

            # Failed, try next mirror
            if i < len(mirror_keys) - 1:
                logger.warning(f"❌ {mirror_name} 失败，切换到备用镜像...")
            else:
                logger.error(f"❌ 所有镜像均失败")

        assert last_result is not None
        return last_result


# Also export fallback order constant for direct access
GO_MIRROR_FALLBACK_ORDER = ["go_qiniu", "go", "go_vip"]
