"""Shared configuration helpers for Context Platform clients."""

from __future__ import annotations

import re
from typing import Final

from pydantic import (
    AnyHttpUrl,
    BaseModel,
    ConfigDict,
    TypeAdapter,
    ValidationError,
    ValidationInfo,
    field_validator,
)

from .exceptions import ConfigError

_API_KEY_PATTERN: Final[re.Pattern[str]] = re.compile(r"^ctxme_[A-Za-z0-9]{32,64}$")
_SERVICE_KEY_PATTERN: Final[re.Pattern[str]] = re.compile(r"^ctxme_svc_[A-Za-z0-9_]{8,}$")
_HTTP_URL_ADAPTER: Final[TypeAdapter[AnyHttpUrl]] = TypeAdapter(AnyHttpUrl)


class BackendConfig(BaseModel):
    """Validated backend configuration shared by CLI and MCP."""

    model_config = ConfigDict(extra="forbid")

    allow_service_keys: bool = False
    api_base_url: AnyHttpUrl
    api_key: str | None = None

    @field_validator("api_key")
    @classmethod
    def _validate_api_key(cls, value: str | None, info: ValidationInfo) -> str | None:
        if value is None:
            return None
        allow_service_keys = info.data.get("allow_service_keys", False)
        return validate_api_key_format(value, allow_service_keys=allow_service_keys)

    @property
    def normalized_base_url(self) -> str:
        """Normalized API base URL without trailing slash."""
        return normalize_api_base_url(str(self.api_base_url))


def validate_api_key_format(value: str, *, allow_service_keys: bool = False) -> str:
    """Validate API key format so tooling fails fast."""
    if not value:
        raise ConfigError("API key must be a non-empty string.")
    if _API_KEY_PATTERN.fullmatch(value):
        return value
    if allow_service_keys and _SERVICE_KEY_PATTERN.fullmatch(value):
        return value
    if allow_service_keys:
        raise ConfigError(
            "API key must match 'ctxme_<32-64 alphanumeric characters>' or 'ctxme_svc_<...>'.",
        )
    raise ConfigError(
        "API key must match pattern 'ctxme_<32-64 alphanumeric characters>'.",
    )


def normalize_api_base_url(raw_url: str) -> str:
    """Ensure the backend URL is valid HTTP(S) and remove trailing slash."""
    if not raw_url:
        raise ConfigError("API base URL cannot be empty.")
    try:
        validated = _HTTP_URL_ADAPTER.validate_python(raw_url)
    except ValidationError as exc:
        raise ConfigError(f"Invalid API base URL '{raw_url}': {exc}") from exc

    normalized = str(validated).rstrip("/")
    return normalized
