"""Convert OpenAPI info, servers, and security schemes to LAPIS [meta] section."""

from __future__ import annotations

from lapis_spec.models.lapis import LapisMeta
from lapis_spec.models.openapi import OpenAPIDict
from lapis_spec.utils import truncate_description


def convert_meta(doc: OpenAPIDict) -> LapisMeta:
    """Build a :class:`LapisMeta` from an OpenAPI document."""
    info = doc.get("info", {})
    servers = doc.get("servers", [])

    api = info.get("title", "Untitled API")
    base = _extract_base_url(servers)
    version = info.get("version")
    desc = truncate_description(info.get("description"))
    auth = _extract_auth(doc)

    return LapisMeta(
        api=api,
        base=base,
        version=version,
        desc=desc,
        auth=auth,
    )


def _extract_base_url(servers: list[dict[str, str]]) -> str:
    if servers and isinstance(servers, list) and servers[0].get("url"):
        url = servers[0]["url"].rstrip("/")
        return url
    return "https://api.example.com"


def _extract_auth(doc: OpenAPIDict) -> str | None:
    """Interpret ``securitySchemes`` into the LAPIS auth compact format."""
    components = doc.get("components", {})
    schemes = components.get("securitySchemes", {})
    if not schemes:
        security = doc.get("security", [])
        if not security:
            return None
        return None

    for _name, scheme in schemes.items():
        if not isinstance(scheme, dict):
            continue
        scheme_type = scheme.get("type", "")
        if scheme_type == "http":
            http_scheme = scheme.get("scheme", "").lower()
            if http_scheme == "bearer":
                return "bearer header:Authorization"
            if http_scheme == "basic":
                return "basic"
        elif scheme_type == "apiKey":
            location = scheme.get("in", "header")
            param_name = scheme.get("name", "X-API-Key")
            return f"apikey {location}:{param_name}"
        elif scheme_type == "oauth2":
            flows = scheme.get("flows", {})
            token_url = None
            for _flow_name, flow_data in flows.items():
                if isinstance(flow_data, dict) and "tokenUrl" in flow_data:
                    token_url = flow_data["tokenUrl"]
                    break
            if token_url:
                return f"oauth2 {token_url}"
            return "oauth2"
        elif scheme_type == "openIdConnect":
            return "bearer header:Authorization"
    return None
