"""
EMU Loader - Load and process EMU configurations.

This module provides utilities for loading EMU configurations,
merging project-level settings, and preparing EMUs for registration.
"""
from __future__ import annotations

import os
from dataclasses import dataclass
from pathlib import Path
from typing import Any

import yaml


@dataclass
class ProjectConfig:
    """Configuration for a project."""

    name: str
    workspace: str | None = None
    project_slug: str | None = None
    default_policy: dict[str, Any] | None = None
    metadata: dict[str, Any] | None = None

    @classmethod
    def from_file(cls, config_path: Path) -> "ProjectConfig":
        """Load project configuration from a YAML file."""
        if not config_path.exists():
            return cls(name=config_path.parent.name)

        with open(config_path) as f:
            data = yaml.safe_load(f) or {}

        return cls(
            name=data.get("name", config_path.parent.name),
            workspace=data.get("workspace"),
            project_slug=data.get("project"),
            default_policy=data.get("default_policy"),
            metadata=data.get("metadata"),
        )


def load_project_config(project_path: Path) -> ProjectConfig:
    """
    Load project configuration from project.yaml or project.yml.

    Args:
        project_path: Path to the project directory

    Returns:
        ProjectConfig (with defaults if no config file exists)
    """
    for filename in ("project.yaml", "project.yml"):
        config_path = project_path / filename
        if config_path.exists():
            return ProjectConfig.from_file(config_path)

    return ProjectConfig(name=project_path.name)


def merge_emu_with_project_config(
    emu_def: dict[str, Any],
    project_config: ProjectConfig,
) -> dict[str, Any]:
    """
    Merge EMU definition with project-level configuration.

    Project-level defaults are applied for missing fields.
    EMU-level settings take precedence.

    Args:
        emu_def: The EMU definition dictionary
        project_config: Project-level configuration

    Returns:
        Merged EMU definition
    """
    result = dict(emu_def)

    # Apply default policy if EMU doesn't have one
    if project_config.default_policy and "policy" not in result:
        result["policy"] = dict(project_config.default_policy)
    elif project_config.default_policy and "policy" in result:
        # Merge policies (EMU takes precedence)
        merged_policy = dict(project_config.default_policy)
        merged_policy.update(result["policy"])
        result["policy"] = merged_policy

    # Add project metadata
    if project_config.metadata:
        emu_metadata = result.get("metadata", {})
        merged_metadata = dict(project_config.metadata)
        merged_metadata.update(emu_metadata)
        result["metadata"] = merged_metadata

    return result


def resolve_env_vars(value: str) -> str:
    """
    Resolve environment variables in a string.

    Supports ${VAR} and $VAR syntax.

    Args:
        value: String potentially containing env var references

    Returns:
        String with env vars resolved
    """
    import re

    def replace_env(match: re.Match[str]) -> str:
        var_name = match.group(1) or match.group(2)
        return os.environ.get(var_name, match.group(0))

    # Match ${VAR} or $VAR patterns
    pattern = r'\$\{([^}]+)\}|\$([A-Za-z_][A-Za-z0-9_]*)'
    return re.sub(pattern, replace_env, value)


def prepare_emu_for_registration(
    emu_def: dict[str, Any],
    workspace: str | None = None,
    project: str | None = None,
) -> dict[str, Any]:
    """
    Prepare an EMU definition for API registration.

    This includes:
    - Resolving any environment variable references
    - Setting default values
    - Validating required fields

    Args:
        emu_def: The EMU definition dictionary
        workspace: Override workspace (from CLI or config)
        project: Override project (from CLI or config)

    Returns:
        Prepared EMU definition ready for API registration
    """
    result = dict(emu_def)

    # Resolve env vars in string fields
    for field in ("emu_key", "trigger", "intent"):
        if field in result and isinstance(result[field], str):
            result[field] = resolve_env_vars(result[field])

    # Set defaults for optional fields
    if "state" not in result:
        result["state"] = "draft"

    if "expected_utility" not in result:
        result["expected_utility"] = 0.5

    if "confidence" not in result:
        result["confidence"] = 0.5

    return result
