"""Harness profile loading and management."""

from __future__ import annotations

from dataclasses import dataclass, field
from pathlib import Path

import yaml


@dataclass
class SymlinkMapping:
    """A symlink from canonical .claude/ to harness-specific location."""

    source: str  # Relative to project root (e.g., .claude/skills)
    target: str  # Relative to project root (e.g., .kiro/skills)


@dataclass
class HarnessProfile:
    """Profile defining how a harness maps to .claude/ config."""

    name: str
    binary: str
    aliases: list[str] = field(default_factory=list)
    config_dir: str = ".claude"
    native: bool = False

    # Context file mapping
    context_source: str = "CLAUDE.md"  # In .claude/
    context_target: str | None = None  # Where harness looks (None = same)

    # Skills directory
    skills_dir: str | None = "skills"  # Relative to config_dir
    skills_format: str = "SKILL.md"

    # MCP config
    mcp_source: str = ".mcp.json"  # In project root
    mcp_target: str | None = None  # Where harness looks (None = same)

    # Install command
    install_command: str | None = None
    install_url: str | None = None

    # Symlinks to create during setup
    symlinks: list[SymlinkMapping] = field(default_factory=list)

    @classmethod
    def from_yaml(cls, path: Path) -> HarnessProfile:
        """Load a profile from a YAML file."""
        with open(path) as f:
            data = yaml.safe_load(f)

        symlinks = []
        setup = data.get("setup", {})
        if setup and isinstance(setup, dict):
            for sl in setup.get("symlinks", []):
                symlinks.append(SymlinkMapping(
                    source=sl["source"],
                    target=sl["target"],
                ))

        # Extract context mapping
        context = data.get("context", {})
        context_source = "CLAUDE.md"
        context_target = None
        if isinstance(context, dict):
            context_source = context.get("source", context.get("project", "CLAUDE.md"))
            project_ctx = context.get("project")
            if project_ctx and project_ctx != "CLAUDE.md":
                context_target = project_ctx

        # Extract skills info
        skills = data.get("skills", {})
        skills_dir = None
        skills_format = "SKILL.md"
        if isinstance(skills, dict):
            skills_dir = skills.get("dir")
            skills_format = skills.get("format", "SKILL.md")

        # Extract MCP info
        mcp = data.get("mcp", {})
        mcp_source = ".mcp.json"
        mcp_target = None
        if isinstance(mcp, dict):
            mcp_config = mcp.get("config", ".mcp.json")
            mcp_source_val = mcp.get("source", mcp_config)
            if mcp_config != mcp_source_val:
                mcp_target = mcp_config
            elif mcp_config != ".mcp.json":
                mcp_target = mcp_config
            mcp_source = mcp_source_val if mcp_source_val else ".mcp.json"

        # Extract install info
        install = data.get("install", {})
        install_command = None
        install_url = None
        if isinstance(install, dict):
            install_command = install.get("command")
            install_url = install.get("url")

        return cls(
            name=data.get("name", path.stem),
            binary=data.get("binary", path.stem),
            aliases=data.get("aliases", []),
            config_dir=data.get("config_dir", ".claude"),
            native=data.get("native", False),
            context_source=context_source,
            context_target=context_target,
            skills_dir=skills_dir,
            skills_format=skills_format,
            mcp_source=mcp_source,
            mcp_target=mcp_target,
            install_command=install_command,
            install_url=install_url,
            symlinks=symlinks,
        )

    def matches(self, name: str) -> bool:
        """Check if this profile matches a given name or alias."""
        return name == self.binary or name in self.aliases


def find_profiles_dir() -> Path:
    """Find the profiles directory."""
    # Check relative to package
    pkg_dir = Path(__file__).parent
    candidates = [
        pkg_dir / "profiles",           # Installed as package data
        pkg_dir.parent.parent / "profiles",  # Development (src layout)
    ]
    for candidate in candidates:
        if candidate.is_dir():
            return candidate
    raise FileNotFoundError("Cannot find profiles directory")


def load_all_profiles() -> list[HarnessProfile]:
    """Load all harness profiles."""
    profiles_dir = find_profiles_dir()
    profiles = []
    for path in sorted(profiles_dir.glob("*.yaml")):
        try:
            profiles.append(HarnessProfile.from_yaml(path))
        except Exception as e:
            # Skip broken profiles
            print(f"Warning: failed to load {path.name}: {e}")
    return profiles


def find_profile(name: str) -> HarnessProfile | None:
    """Find a profile by name or alias."""
    for profile in load_all_profiles():
        if profile.matches(name):
            return profile
    return None
