"""Go binary building with 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 apply_mirror_environment, MIRROR_CONFIGS


class GoBinaryBuilder:
    """Build Go binaries with optional mirror failover."""

    MIRROR_KEYS = ["go_qiniu", "go", "go_vip"]

    @staticmethod
    def build_with_failover(
        go_executable: str,
        source_dir: Path,
        output_path: Path,
        env: dict[str, str],
        ldflags: str | None,
        tags: list[str] | None,
        target: str | Path | None,
        run_build,
        stream_output: bool = True,
    ) -> BuildResult:
        """Build binary with automatic mirror failover.

        Args:
            go_executable: Path to Go executable
            source_dir: Source directory
            output_path: Output path for binary
            env: Environment variables
            ldflags: Linker flags
            tags: Build tags
            target: Build target
            run_build: Callback to execute build
            stream_output: Whether to stream output

        Returns:
            BuildResult with success status
        """
        last_result: BuildResult | None = None

        for i, mirror_key in enumerate(GoBinaryBuilder.MIRROR_KEYS):
            env_copy = env.copy()
            mirror_name = MIRROR_CONFIGS.get(mirror_key, {}).get("name", mirror_key)
            logger.info(f"🔗 使用代理: {mirror_name}")
            env_copy = apply_mirror_environment(mirror_key, env_copy)

            build_args = [go_executable, "build", "-o", str(output_path)]

            if ldflags:
                build_args.extend(["-ldflags", ldflags])
            if tags:
                build_args.extend(["-tags", ",".join(tags)])
            if target:
                build_args.append(str(target))

            logger.info(f"构建命令: {' '.join(build_args)}")
            result = run_build(build_args, source_dir, output_path.parent, env_copy)
            last_result = result

            if result["success"]:
                logger.info("✅ 构建成功")
                return result

            if i < len(GoBinaryBuilder.MIRROR_KEYS) - 1:
                logger.warning(f"❌ {mirror_name} 失败，切换到备用镜像...")

        assert last_result is not None
        return last_result

    @staticmethod
    def build_single(
        go_executable: str,
        source_dir: Path,
        output_path: Path,
        env: dict[str, str],
        ldflags: str | None,
        tags: list[str] | None,
        target: str | Path | None,
        run_build,
        stream_output: bool = True,
    ) -> BuildResult:
        """Build binary with single mirror.

        Args:
            go_executable: Path to Go executable
            source_dir: Source directory
            output_path: Output path for binary
            env: Environment variables
            ldflags: Linker flags
            tags: Build tags
            target: Build target
            run_build: Callback to execute build
            stream_output: Whether to stream output

        Returns:
            BuildResult with success status
        """
        build_args = [go_executable, "build", "-o", str(output_path)]

        if ldflags:
            build_args.extend(["-ldflags", ldflags])
        if tags:
            build_args.extend(["-tags", ",".join(tags)])
        if target:
            build_args.append(str(target))

        logger.info("🔨 开始构建...")
        logger.info(f"构建命令: {' '.join(build_args)}")
        build_result = run_build(build_args, source_dir, output_path.parent, env)

        if build_result["success"]:
            logger.info("✅ 构建成功")

        return build_result
