"""Unit tests for HistoryManager."""

import json
from datetime import datetime
from pathlib import Path

import pytest

from tools.history.manager import HistoryManager, LENS_MAPPING
from tools.workflow.confidence import ConfidenceLevel
from tools.workflow.state import StepHistory, WorkflowState


@pytest.fixture
def temp_history_dir(tmp_path: Path) -> Path:
    """Create a temporary history directory."""
    return tmp_path / ".optix" / "history"


@pytest.fixture
def sample_workflow_state() -> WorkflowState:
    """Create a sample completed WorkflowState."""
    state = WorkflowState(
        continuation_id="test-abc-123",
        tool_name="security_audit",
        project_root_path="/path/to/project",
    )
    step1 = StepHistory(
        step_number=1,
        step_content="Discovery",
        findings='[{"severity": "high", "category": "SQL Injection", "description": "Unsafe query"}]',
        confidence=ConfidenceLevel.MEDIUM,
        files_checked=["src/db.py", "src/api.py"],
        timestamp=datetime(2026, 1, 29, 14, 30, 0),
    )
    step2 = StepHistory(
        step_number=2,
        step_content="Analysis",
        findings="[]",
        confidence=ConfidenceLevel.HIGH,
        files_checked=["src/auth.py"],
        timestamp=datetime(2026, 1, 29, 14, 32, 0),
    )
    state.add_step(step1)
    state.add_step(step2)
    state.is_finished = True
    return state


class TestHistoryManagerInit:
    def test_init_sets_base_dir(self, temp_history_dir: Path):
        manager = HistoryManager(temp_history_dir)
        assert manager.base_dir == temp_history_dir

    def test_version_is_set(self, temp_history_dir: Path):
        manager = HistoryManager(temp_history_dir)
        assert manager.VERSION == "1.0"


class TestSaveAudit:
    def test_creates_directory_structure(
        self, temp_history_dir: Path, sample_workflow_state: WorkflowState
    ):
        manager = HistoryManager(temp_history_dir)
        result_path = manager.save_audit(sample_workflow_state)

        assert result_path.exists()
        assert result_path.is_dir()
        assert (result_path / "audit.json").exists()

    def test_directory_name_format(
        self, temp_history_dir: Path, sample_workflow_state: WorkflowState
    ):
        manager = HistoryManager(temp_history_dir)
        result_path = manager.save_audit(sample_workflow_state)

        dir_name = result_path.name
        parts = dir_name.split("_")
        assert len(parts) >= 3
        assert parts[-1] == "security"

    def test_audit_json_contains_required_fields(
        self, temp_history_dir: Path, sample_workflow_state: WorkflowState
    ):
        manager = HistoryManager(temp_history_dir)
        result_path = manager.save_audit(sample_workflow_state)

        with open(result_path / "audit.json") as f:
            data = json.load(f)

        assert "version" in data
        assert "timestamp" in data
        assert "lens" in data
        assert "continuation_id" in data
        assert "project" in data
        assert "summary" in data
        assert "findings" in data
        assert "step_history" in data
        assert "files_checked" in data
        assert "confidence" in data

    def test_lens_mapping_applied(
        self, temp_history_dir: Path, sample_workflow_state: WorkflowState
    ):
        manager = HistoryManager(temp_history_dir)
        result_path = manager.save_audit(sample_workflow_state)

        with open(result_path / "audit.json") as f:
            data = json.load(f)

        assert data["lens"] == "security"

    def test_continuation_id_preserved(
        self, temp_history_dir: Path, sample_workflow_state: WorkflowState
    ):
        manager = HistoryManager(temp_history_dir)
        result_path = manager.save_audit(sample_workflow_state)

        with open(result_path / "audit.json") as f:
            data = json.load(f)

        assert data["continuation_id"] == "test-abc-123"


class TestStateToSnapshot:
    def test_summary_contains_expected_fields(
        self, temp_history_dir: Path, sample_workflow_state: WorkflowState
    ):
        manager = HistoryManager(temp_history_dir)
        snapshot = manager._state_to_snapshot(sample_workflow_state)

        summary = snapshot["summary"]
        assert "total_findings" in summary
        assert "by_severity" in summary
        assert "files_examined" in summary
        assert "steps_completed" in summary
        assert "duration_seconds" in summary

    def test_by_severity_has_all_levels(
        self, temp_history_dir: Path, sample_workflow_state: WorkflowState
    ):
        manager = HistoryManager(temp_history_dir)
        snapshot = manager._state_to_snapshot(sample_workflow_state)

        by_severity = snapshot["summary"]["by_severity"]
        assert "critical" in by_severity
        assert "high" in by_severity
        assert "medium" in by_severity
        assert "low" in by_severity
        assert "info" in by_severity

    def test_project_name_extracted_from_path(
        self, temp_history_dir: Path, sample_workflow_state: WorkflowState
    ):
        manager = HistoryManager(temp_history_dir)
        snapshot = manager._state_to_snapshot(sample_workflow_state)

        assert snapshot["project"]["name"] == "project"
        assert snapshot["project"]["root_path"] == "/path/to/project"

    def test_step_history_formatted(
        self, temp_history_dir: Path, sample_workflow_state: WorkflowState
    ):
        manager = HistoryManager(temp_history_dir)
        snapshot = manager._state_to_snapshot(sample_workflow_state)

        assert len(snapshot["step_history"]) == 2
        first_step = snapshot["step_history"][0]
        assert first_step["step_number"] == 1
        assert first_step["name"] == "Discovery"
        assert "files_examined" in first_step
        assert "timestamp" in first_step


class TestLensMapping:
    @pytest.mark.parametrize(
        "tool_name,expected_lens",
        [
            ("security_audit", "security"),
            ("a11y_audit", "a11y"),
            ("devops_audit", "devops"),
            ("principal_audit", "principal"),
        ],
    )
    def test_lens_mapping_values(self, tool_name: str, expected_lens: str):
        assert LENS_MAPPING[tool_name] == expected_lens

    def test_unknown_tool_uses_tool_name(self, temp_history_dir: Path):
        state = WorkflowState(
            continuation_id="test-123",
            tool_name="custom_audit",
            project_root_path="/project",
        )
        manager = HistoryManager(temp_history_dir)
        snapshot = manager._state_to_snapshot(state)

        assert snapshot["lens"] == "custom_audit"


class TestEdgeCases:
    def test_state_without_project_root_path(self, temp_history_dir: Path):
        state = WorkflowState(
            continuation_id="test-123",
            tool_name="security_audit",
            project_root_path=None,
        )
        manager = HistoryManager(temp_history_dir)
        snapshot = manager._state_to_snapshot(state)

        assert snapshot["project"]["name"] is None
        assert snapshot["project"]["root_path"] is None

    def test_state_without_steps(self, temp_history_dir: Path):
        state = WorkflowState(
            continuation_id="test-123",
            tool_name="security_audit",
            project_root_path="/project",
        )
        manager = HistoryManager(temp_history_dir)
        snapshot = manager._state_to_snapshot(state)

        assert snapshot["step_history"] == []
        assert snapshot["summary"]["steps_completed"] == 0
        assert snapshot["summary"]["duration_seconds"] is None

    def test_state_with_consolidated_none(self, temp_history_dir: Path):
        state = WorkflowState(
            continuation_id="test-123",
            tool_name="security_audit",
            project_root_path="/project",
        )
        state.consolidated = None
        manager = HistoryManager(temp_history_dir)
        snapshot = manager._state_to_snapshot(state)

        assert snapshot["summary"]["total_findings"] == 0
        assert snapshot["findings"] == []
        assert snapshot["files_checked"] == []
