"""
Agent Card — A2A-compliant agent discovery.
Part of #843: fix: implement A2A agent card for fleet discovery (#819)

Provides metadata about the agent's identity, capabilities, and installed skills
for discovery by other agents in the fleet.
"""

import json
import logging
import os
from dataclasses import asdict, dataclass, field
from pathlib import Path
from typing import Any, Dict, List, Optional

from hermes_cli import __version__
from hermes_cli.config import load_config, get_hermes_home
from agent.skill_utils import (
    iter_skill_index_files,
    parse_frontmatter,
    get_all_skills_dirs,
    get_disabled_skill_names,
    skill_matches_platform
)

logger = logging.getLogger(__name__)

@dataclass
class AgentSkill:
    id: str
    name: str
    description: str = ""
    version: str = "1.0.0"

@dataclass
class AgentCapabilities:
    streaming: bool = True
    tools: bool = True
    vision: bool = False
    reasoning: bool = False

@dataclass
class AgentCard:
    name: str
    description: str
    url: str
    version: str = __version__
    capabilities: AgentCapabilities = field(default_factory=AgentCapabilities)
    skills: List[AgentSkill] = field(default_factory=list)
    defaultInputModes: List[str] = field(default_factory=lambda: ["text/plain"])
    defaultOutputModes: List[str] = field(default_factory=lambda: ["text/plain"])

def _load_skills() -> List[AgentSkill]:
    """Scan all enabled skills and return metadata."""
    skills = []
    disabled = get_disabled_skill_names()
    
    for skills_dir in get_all_skills_dirs():
        if not skills_dir.is_dir():
            continue
        for skill_file in iter_skill_index_files(skills_dir, "SKILL.md"):
            try:
                raw = skill_file.read_text(encoding="utf-8")
                frontmatter, _ = parse_frontmatter(raw)
            except Exception:
                continue

            skill_name = frontmatter.get("name") or skill_file.parent.name
            if str(skill_name) in disabled:
                continue
            if not skill_matches_platform(frontmatter):
                continue

            skills.append(AgentSkill(
                id=str(skill_name),
                name=str(frontmatter.get("name", skill_name)),
                description=str(frontmatter.get("description", "")),
                version=str(frontmatter.get("version", "1.0.0"))
            ))
    return skills

def build_agent_card() -> AgentCard:
    """Build the agent card from current configuration and environment."""
    config = load_config()
    
    # Identity
    name = os.environ.get("HERMES_AGENT_NAME") or config.get("agent", {}).get("name") or "hermes"
    description = os.environ.get("HERMES_AGENT_DESCRIPTION") or config.get("agent", {}).get("description") or "Sovereign AI agent"
    
    # URL - try to determine from environment or config
    port = os.environ.get("HERMES_WEB_PORT") or "9119"
    host = os.environ.get("HERMES_WEB_HOST") or "localhost"
    url = f"http://{host}:{port}"
    
    # Capabilities
    # In a real scenario, we'd check model metadata for vision/reasoning
    capabilities = AgentCapabilities(
        streaming=True,
        tools=True,
        vision=False, # Default to false unless we can confirm
        reasoning=False
    )
    
    # Skills
    skills = _load_skills()
    
    return AgentCard(
        name=name,
        description=description,
        url=url,
        version=__version__,
        capabilities=capabilities,
        skills=skills
    )

def get_agent_card_json() -> str:
    """Return the agent card as a JSON string."""
    try:
        card = build_agent_card()
        return json.dumps(asdict(card), indent=2)
    except Exception as e:
        logger.error(f"Failed to build agent card: {e}")
        # Minimal fallback card
        fallback = {
            "name": "hermes",
            "description": "Sovereign AI agent (fallback)",
            "version": __version__,
            "error": str(e)
        }
        return json.dumps(fallback, indent=2)

def validate_agent_card(card_data: Dict[str, Any]) -> bool:
    """Check if the card data complies with the A2A schema."""
    required = ["name", "description", "url", "version"]
    return all(k in card_data for k in required)
