"""Pydantic schema for adk.config.json."""

from enum import Enum
from pathlib import Path
from typing import Literal, Optional

from pydantic import BaseModel, Field, model_validator


class AuthType(str, Enum):
    api_key = "api_key"
    bearer = "bearer"
    oauth2 = "oauth2"


class ADKConfig(BaseModel):
    """Config stored in adk.config.json. Either openapi_url or openapi_path must be set."""

    openapi_url: Optional[str] = Field(default=None, description="URL to OpenAPI spec (YAML or JSON)")
    openapi_path: Optional[str] = Field(default=None, description="Local path to OpenAPI spec file")
    product_name: str = Field(..., description="Product name for system prompt")
    product_description: Optional[str] = Field(default=None, description="Short product description")
    base_url: str = Field(..., description="API base URL for tool requests")
    auth_type: AuthType = Field(default=AuthType.bearer, description="Auth type for SaaS API")
    auth_env_var: str = Field(..., description="Env var name for API key/token (e.g. ACME_API_KEY)")
    output_dir: str = Field(default="./agent", description="Directory for generated agent files")
    llm_provider: Literal["openai", "anthropic", "gemini", "ollama"] = Field(default="openai", description="LLM provider for agent")
    model: str = Field(default="gpt-4o-mini", description="Model name for agent")

    def get_openapi_source(self) -> str:
        """Return the OpenAPI source (URL or path) for loading."""
        if self.openapi_url:
            return self.openapi_url
        if self.openapi_path:
            return self.openapi_path
        raise ValueError("Either openapi_url or openapi_path must be set")

    def is_openapi_url(self) -> bool:
        return self.openapi_url is not None

    @model_validator(mode="after")
    def require_openapi_source(self) -> "ADKConfig":
        if not self.openapi_url and not self.openapi_path:
            raise ValueError("Either openapi_url or openapi_path must be set")
        if self.openapi_url and self.openapi_path:
            raise ValueError("Set only one of openapi_url or openapi_path")
        return self
