# Copyright (C) 2026 GoodData Corporation

"""Parsing helpers for validation registry YAML content."""

from __future__ import annotations

from collections.abc import Mapping
from typing import Any, cast

from aida_mcp.tools.core.validation_registry_model import CommandSpec, ProcessorSpec


def string_mapping(raw: object) -> dict[str, Any]:
    if not isinstance(raw, Mapping):
        return {}
    out: dict[str, Any] = {}
    m = cast(Mapping[object, object], raw)
    for k, v in m.items():
        out[str(k)] = v
    return out


def string_list(raw: object) -> list[str]:
    if not isinstance(raw, list):
        return []
    items = cast(list[object], raw)
    if not all(isinstance(x, str) for x in items):
        return []
    return cast(list[str], items)


def parse_command_spec(raw: object) -> CommandSpec | None:
    if not isinstance(raw, Mapping):
        return None
    m = string_mapping(cast(object, raw))
    argv = string_list(m.get("argv"))
    if not argv:
        return None
    cwd_any = m.get("cwd")
    cwd = cwd_any if isinstance(cwd_any, str) and cwd_any else None
    env: dict[str, str] = {}
    env_any = m.get("env")
    if isinstance(env_any, Mapping):
        env_map = cast(Mapping[object, object], env_any)
        for k, v in env_map.items():
            if isinstance(v, str):
                env[str(k)] = v
    timeout_any = m.get("timeout_sec")
    timeout_sec = timeout_any if isinstance(timeout_any, int) and timeout_any > 0 else None
    streaming_any = m.get("streaming")
    streaming = streaming_any if isinstance(streaming_any, bool) else True
    return CommandSpec(argv=argv, cwd=cwd, env=env, timeout_sec=timeout_sec, streaming=streaming)


def parse_processor_spec(raw: object) -> ProcessorSpec | None:
    if not isinstance(raw, Mapping):
        return None
    m = string_mapping(cast(object, raw))
    module_any = m.get("module")
    module = module_any if isinstance(module_any, str) and module_any else None
    builtin_id_any = m.get("builtin_id")
    builtin_id = builtin_id_any if isinstance(builtin_id_any, str) and builtin_id_any.strip() else None
    argv_list = string_list(m.get("argv"))
    argv = argv_list if argv_list else None
    timeout_any = m.get("timeout_sec")
    timeout_sec = timeout_any if isinstance(timeout_any, int) and timeout_any > 0 else None
    env: dict[str, str] = {}
    env_any = m.get("env")
    if isinstance(env_any, Mapping):
        env_map = cast(Mapping[object, object], env_any)
        for k, v in env_map.items():
            if isinstance(v, str):
                env[str(k)] = v
    kind_any = m.get("kind")
    kind = kind_any if isinstance(kind_any, str) and kind_any else "builtin"
    if kind != "builtin" or not builtin_id:
        return None
    return ProcessorSpec(kind=kind, builtin_id=builtin_id, module=module, argv=argv, timeout_sec=timeout_sec, env=env)
