from __future__ import annotations

from pathlib import Path

import pytest

from core.agent.crewai.template_loader import (
    load_crewai_template,
    load_tools_whitelist,
    validate_workflow_stages,
)


def _write(path: Path, content: str) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(content, encoding="utf-8")


def _prepare_static_root(root: Path) -> Path:
    _write(
        root / "agents.yaml",
        """
intent:
  role: Intent Agent
execution:
  role: Execution Agent
organization:
  role: Organization Agent
""".strip(),
    )
    _write(
        root / "tasks.yaml",
        """
intent:
  description: classify
execution:
  description: run task
organization:
  description: summarize
""".strip(),
    )
    _write(
        root / "workflow.yaml",
        """
stages:
  - intent
  - execution
  - organization
""".strip(),
    )
    _write(
        root / "tools.yaml",
        """
tools:
  - asr_fun_asr
  - doc_extract
""".strip(),
    )
    return root


def test_load_crewai_template_success_when_all_files_valid(tmp_path: Path) -> None:
    static_root = _prepare_static_root(tmp_path)

    template = load_crewai_template(static_root)

    assert set(template.agents.keys()) == {"intent", "execution", "organization"}
    assert set(template.tasks.keys()) == {"intent", "execution", "organization"}
    assert template.workflow["stages"] == ["intent", "execution", "organization"]
    assert template.tools_whitelist == {"asr_fun_asr", "doc_extract"}


def test_load_crewai_template_raises_file_not_found_when_required_file_missing(
    tmp_path: Path,
) -> None:
    static_root = _prepare_static_root(tmp_path)
    (static_root / "tasks.yaml").unlink()

    with pytest.raises(FileNotFoundError):
        load_crewai_template(static_root)


def test_load_crewai_template_raises_value_error_when_workflow_stages_invalid(
    tmp_path: Path,
) -> None:
    static_root = _prepare_static_root(tmp_path)
    _write(
        static_root / "workflow.yaml",
        """
stages:
  - execution
  - intent
  - organization
""".strip(),
    )

    with pytest.raises(ValueError):
        load_crewai_template(static_root)


def test_load_tools_whitelist_from_tools_yaml(tmp_path: Path) -> None:
    static_root = _prepare_static_root(tmp_path)

    whitelist = load_tools_whitelist(static_root)

    assert whitelist == {"asr_fun_asr", "doc_extract"}


def test_validate_workflow_stages_accepts_exact_intent_execution_organization() -> None:
    validate_workflow_stages(["intent", "execution", "organization"])


def test_validate_workflow_stages_rejects_extra_or_missing_stage() -> None:
    with pytest.raises(ValueError):
        validate_workflow_stages(["intent", "execution"])
    with pytest.raises(ValueError):
        validate_workflow_stages(["intent", "execution", "organization", "extra"])


def test_load_tools_whitelist_rejects_non_string_item(tmp_path: Path) -> None:
    static_root = _prepare_static_root(tmp_path)
    _write(
        static_root / "tools.yaml",
        """
tools:
  - asr_fun_asr
  - 123
""".strip(),
    )

    with pytest.raises(ValueError):
        load_tools_whitelist(static_root)
