#!/usr/bin/env python3
"""
Prompt definitions and parsing for MCP server.

This module handles the parsing and validation of prompt configurations
from YAML files, similar to how tools.py handles tool configurations.
"""

from dataclasses import dataclass


@dataclass
class PromptArgument:
    """Represents an argument for a prompt."""

    description: str
    required: bool


@dataclass
class PromptInfo:
    """Represents a prompt with its metadata and arguments."""

    name: str
    description: str
    template: str
    arguments: dict[str, PromptArgument]


def validate_prompt_config(prompt_name: str, prompt_config: dict) -> None:
    """
    Validate a prompt configuration.

    Args:
        prompt_name: The name of the prompt.
        prompt_config: The prompt configuration dictionary.

    Raises:
        ValueError: If the prompt configuration is invalid.
    """
    if not isinstance(prompt_config, dict):
        raise ValueError(f"Prompt '{prompt_name}' must be a dictionary")

    if 'description' not in prompt_config:
        raise ValueError(f"Prompt '{prompt_name}' must contain a 'description'")

    if not isinstance(prompt_config['description'], str):
        raise ValueError(f"Prompt '{prompt_name}' description must be a string")

    if 'template' not in prompt_config:
        raise ValueError(f"Prompt '{prompt_name}' must contain a 'template'")

    if not isinstance(prompt_config['template'], str):
        raise ValueError(f"Prompt '{prompt_name}' template must be a string")

    # Arguments are optional
    if 'arguments' in prompt_config:
        if not isinstance(prompt_config['arguments'], dict):
            raise ValueError(f"Prompt '{prompt_name}' arguments must be a dictionary")

        for arg_name, arg_config in prompt_config['arguments'].items():
            validate_prompt_argument_config(prompt_name, arg_name, arg_config)


def validate_prompt_argument_config(prompt_name: str, arg_name: str, arg_config: dict) -> None:
    """
    Validate a prompt argument configuration.

    Args:
        prompt_name: The name of the prompt.
        arg_name: The name of the argument.
        arg_config: The argument configuration dictionary.

    Raises:
        ValueError: If the argument configuration is invalid.
    """
    if not isinstance(arg_config, dict):
        raise ValueError(f"Argument '{arg_name}' in prompt '{prompt_name}' must be a dictionary")

    if 'description' not in arg_config:
        raise ValueError(
            f"Argument '{arg_name}' in prompt '{prompt_name}' must contain a 'description'",
        )

    if not isinstance(arg_config['description'], str):
        raise ValueError(
            f"Argument '{arg_name}' description in prompt '{prompt_name}' must be a string",
        )

    if 'required' not in arg_config:
        raise ValueError(
            f"Argument '{arg_name}' in prompt '{prompt_name}' must contain a 'required' field",
        )

    if not isinstance(arg_config['required'], bool):
        raise ValueError(
            f"Argument '{arg_name}' required field in prompt '{prompt_name}' must be a boolean",
        )


def parse_prompts(config: dict) -> list[PromptInfo]:
    """
    Parse prompt configurations from the config dictionary.

    Args:
        config: The configuration dictionary containing prompts.

    Returns:
        List of PromptInfo objects.

    Raises:
        ValueError: If the configuration is invalid.
    """
    prompts_info = []

    # Prompts section is optional
    if 'prompts' not in config:
        return prompts_info

    if not isinstance(config['prompts'], dict):
        raise ValueError("'prompts' must be a dictionary")

    for prompt_name, prompt_config in config['prompts'].items():
        validate_prompt_config(prompt_name, prompt_config)

        # Parse arguments
        arguments = {}
        if 'arguments' in prompt_config:
            for arg_name, arg_config in prompt_config['arguments'].items():
                arguments[arg_name] = PromptArgument(
                    description=arg_config['description'],
                    required=arg_config['required'],
                )

        prompt_info = PromptInfo(
            name=prompt_name,
            description=prompt_config['description'],
            template=prompt_config['template'],
            arguments=arguments,
        )

        prompts_info.append(prompt_info)

    return prompts_info
