"""
Configuration module for {{ agent_display_name }}
Centralizes all environment variables and configuration settings
"""

import os
import json
from pathlib import Path
from typing import Optional

from a2a.types import AgentCard


class AgentConfig:
    """Configuration class for {{ agent_display_name }}"""
    
    # Agent Identity
    AGENT_NAME: str = "{{ agent_name }}"
    AGENT_DISPLAY_NAME: str = "{{ agent_display_name }}"
    AGENT_DESCRIPTION: str = "{{ agent_description }}"
    
    # Ports
    AGENT_PORT: int = int(os.getenv('AGENT_PORT', '{{ agent_port }}'))
    SERVICE_PORT: int = int(os.getenv('SERVICE_PORT', '{{ agent_port }}'))
    {% if with_web_interface %}
    WEB_INTERFACE_PORT: int = int(os.getenv('WEB_INTERFACE_PORT', '{{ web_interface_port }}'))
    {% endif %}
    
    # Model Configuration
    MODEL_NAME: str = os.getenv('MODEL_NAME', '{{ model_name }}')
    OLLAMA_HOST: str = os.getenv('OLLAMA_HOST', 'http://{{ project_dir }}-ollama:11434')
    
    # LLM Configuration (unified dict for create_llm)
    LLM_CONFIG: dict = {
        "provider": os.getenv("LLM_PROVIDER", "ollama"),
        "model": os.getenv("MODEL_NAME", "{{ model_name }}"),
        "temperature": float(os.getenv("LLM_TEMPERATURE", "0.1")),
        "base_url": os.getenv("LLM_BASE_URL", os.getenv("OLLAMA_HOST", "http://{{ project_dir }}-ollama:11434")),
        "api_key": os.getenv("LLM_API_KEY", ""),
        # Cloud-specific (only used when provider requires them)
        "aws_region": os.getenv("AWS_REGION", "us-east-1"),
        "azure_deployment": os.getenv("AZURE_DEPLOYMENT", ""),
        "azure_endpoint": os.getenv("AZURE_ENDPOINT", ""),
        "vertex_project": os.getenv("VERTEX_PROJECT", ""),
        "vertex_location": os.getenv("VERTEX_LOCATION", "us-central1"),
    }
    
    # Logging
    LOG_LEVEL: str = os.getenv('LOG_LEVEL', 'INFO')
    
    # ABI Configuration
    ABI_ROLE: str = os.getenv('ABI_ROLE', '{{ agent_display_name }}')
    ABI_NODE: str = os.getenv('ABI_NODE', 'ABI Node')
    
    # Semantic Layer
    SEMANTIC_LAYER_HOST: str = os.getenv('SEMANTIC_LAYER_HOST', 'http://{{ project_dir }}-semantic-layer:10100')
    MCP_HOST: str = os.getenv('MCP_HOST', '{{ project_dir }}-semantic-layer')
    MCP_PORT: int = int(os.getenv('MCP_PORT', '10100'))
    MCP_TRANSPORT: str = os.getenv('MCP_TRANSPORT', 'streamable-http')
    
    # Agent Card
    AGENT_CARD: str = os.getenv('AGENT_CARD', './agent_cards/{{ agent_name }}_agent.json')
    
    # A2A Validation
    A2A_VALIDATION_MODE: str = os.getenv('A2A_VALIDATION_MODE', 'permissive')
    A2A_ENABLE_AUDIT_LOG: bool = os.getenv('A2A_ENABLE_AUDIT_LOG', 'true').lower() == 'true'
    GUARDIAN_URL: str = os.getenv('GUARDIAN_URL', 'http://{{ project_dir }}-guardian:11438')
    OPA_URL: str = os.getenv('OPA_URL', 'http://{{ project_dir }}-opa:8181')
    
    # Ollama Configuration (for distributed mode)
    START_OLLAMA: bool = os.getenv('START_OLLAMA', 'false').lower() == 'true'
    LOAD_MODELS: bool = os.getenv('LOAD_MODELS', 'false').lower() == 'true'
    
    # Service Module
    SERVICE_MODULE: str = os.getenv('SERVICE_MODULE', 'main')
    
    @classmethod
    def get_ollama_url(cls) -> str:
        """Get the complete Ollama URL"""
        return cls.OLLAMA_HOST
    
    @classmethod
    def get_semantic_layer_url(cls) -> str:
        """Get the complete Semantic Layer URL"""
        return cls.SEMANTIC_LAYER_HOST
    
    @classmethod
    def is_distributed_mode(cls) -> bool:
        """Check if running in distributed Ollama mode"""
        return cls.START_OLLAMA
    
    @classmethod
    def display_config(cls) -> dict:
        """Return configuration as dictionary for display"""
        return {
            'agent_name': cls.AGENT_NAME,
            'agent_display_name': cls.AGENT_DISPLAY_NAME,
            'agent_port': cls.AGENT_PORT,
            'model_name': cls.MODEL_NAME,
            'ollama_host': cls.OLLAMA_HOST,
            'semantic_layer_host': cls.SEMANTIC_LAYER_HOST,
            'log_level': cls.LOG_LEVEL,
            'distributed_mode': cls.is_distributed_mode()
        }


# Create a singleton instance
config = AgentConfig()


# Load agent card at module import time
def _load_agent_card() -> AgentCard:
    """
    Load and validate the agent card from file
    
    Returns:
        AgentCard: The loaded agent card object
        
    Raises:
        FileNotFoundError: If agent card file doesn't exist
        json.JSONDecodeError: If agent card JSON is invalid
        ValueError: If agent card name doesn't match expected
    """
    card_path = Path(config.AGENT_CARD)
    
    if not card_path.exists():
        raise FileNotFoundError(f"Agent card not found: {config.AGENT_CARD}")
    
    try:
        with card_path.open() as f:
            data = json.load(f)
        
        agent_card = AgentCard(**data)
        
        # Validate agent card name
        if agent_card.name != config.AGENT_DISPLAY_NAME:
            raise ValueError(
                f"Agent card name mismatch. "
                f"Expected: {config.AGENT_DISPLAY_NAME}, "
                f"Got: {agent_card.name}"
            )
        
        return agent_card
        
    except json.JSONDecodeError as e:
        raise json.JSONDecodeError(
            f"Invalid JSON in agent card {config.AGENT_CARD}: {e.msg}",
            e.doc,
            e.pos
        )


# Agent card loaded at import time - ready to use
AGENT_CARD = _load_agent_card()
