"""Airspeed Velocity benchmarks for plan generation workflows.

Measures invoke and streaming performance of PlanGenerationGraph using
built-in FakeListLLM responses and minimal domain models.
"""

from __future__ import annotations

from pathlib import Path

import tiktoken
from langchain_community.llms import FakeListLLM

from cleveragents.agents.graphs.plan_generation import PlanGenerationGraph
from cleveragents.domain.models.core import (
    Context,
    ContextType,
    Plan,
    PlanStatus,
    Project,
)
from cleveragents.domain.models.core.project_legacy import ProjectSettings


def _sample_project() -> Project:
    return Project(
        id=1,
        name="bench-project",
        path=Path(".").resolve(),
        settings=ProjectSettings(
            auto_build=False,
            auto_apply=False,
            confirm_apply=True,
            max_context_size=52_428_800,
            default_model="mock-gpt",
        ),
        current_plan_id=1,
    )


def _sample_plan() -> Plan:
    return Plan(
        id=1,
        project_id=1,
        name="bench-plan",
        prompt="Add error handling",
        status=PlanStatus.PENDING,
        current=True,
        build=None,
        build_started_at=None,
        build_completed_at=None,
        model_used=None,
        token_count=None,
        result=None,
        applied_at=None,
        files_created=None,
        files_modified=None,
        files_deleted=None,
    )


def _sample_contexts() -> list[Context]:
    return [
        Context(
            id=1,
            plan_id=1,
            type=ContextType.FILE,
            path="src/example.py",
            content="print('hello')",
            file_hash=None,
            size=18,
        )
    ]


class PlanGenerationSuite:
    """Benchmark PlanGenerationGraph invoke and stream paths."""

    def setup(self) -> None:
        self.graph = PlanGenerationGraph(
            llm=FakeListLLM(responses=["bench response"] * 3)
        )
        self.project = _sample_project()
        self.plan = _sample_plan()
        self.contexts = _sample_contexts()

        enc = tiktoken.get_encoding("cl100k_base")
        self.prompt_tokens = {
            "analyze": len(enc.encode(self.graph.analyze_prompt.template)),
            "generate": len(enc.encode(self.graph.generate_prompt.template)),
            "validate": len(enc.encode(self.graph.validate_prompt.template)),
        }

    def time_invoke(self) -> None:
        self.graph.invoke(self.project, self.plan, self.contexts, thread_id="bench")

    def time_stream(self) -> None:
        for _ in self.graph.stream(self.project, self.plan, self.contexts):
            pass

    def track_analyze_prompt_tokens(self) -> int:
        return self.prompt_tokens["analyze"]

    def track_generate_prompt_tokens(self) -> int:
        return self.prompt_tokens["generate"]

    def track_validate_prompt_tokens(self) -> int:
        return self.prompt_tokens["validate"]
