"""Unit tests for ViewHistoryTool."""

import json
from pathlib import Path
from unittest.mock import patch

import pytest

from tools.view_history.tool import ViewHistoryTool, ViewHistoryResponse


@pytest.fixture
def temp_project_dir(tmp_path: Path) -> Path:
    """Create a temporary project directory."""
    return tmp_path / "my-project"


@pytest.fixture
def sample_audit_data() -> dict:
    """Sample audit.json data."""
    return {
        "version": "1.0",
        "timestamp": "2026-01-29T14:30:45",
        "lens": "security",
        "continuation_id": "test-abc-123",
        "project": {"name": "my-project", "root_path": "/path/to/project"},
        "summary": {
            "total_findings": 5,
            "by_severity": {"critical": 0, "high": 2, "medium": 2, "low": 1, "info": 0},
            "files_examined": 42,
            "steps_completed": 6,
        },
        "findings": [
            {
                "severity": "high",
                "category": "SQL Injection",
                "description": "Unsafe query",
                "affected_files": ["src/db.py"],
            }
        ],
    }


def create_audit_dir(project_dir: Path, dir_name: str, audit_data: dict) -> Path:
    """Helper to create an audit directory with data."""
    history_dir = project_dir / ".optix" / "history"
    audit_dir = history_dir / dir_name
    audit_dir.mkdir(parents=True, exist_ok=True)
    audit_file = audit_dir / "audit.json"
    with open(audit_file, "w", encoding="utf-8") as f:
        json.dump(audit_data, f)
    return audit_dir


class TestViewHistoryToolInit:
    def test_name_property(self):
        tool = ViewHistoryTool()
        assert tool.name == "view_history"

    def test_description_property(self):
        tool = ViewHistoryTool()
        assert "HTML" in tool.description
        assert "browser" in tool.description


class TestViewHistoryToolExecute:
    @patch("webbrowser.open")
    def test_returns_success_with_audits(
        self, mock_browser, temp_project_dir: Path, sample_audit_data: dict
    ):
        temp_project_dir.mkdir(parents=True)
        create_audit_dir(
            temp_project_dir, "2026-01-29_14-30-45_security", sample_audit_data
        )

        tool = ViewHistoryTool()
        result = tool.execute(project_path=str(temp_project_dir))

        assert result.success is True
        assert result.audit_count == 1
        assert result.html_path is not None
        assert "history_viewer.html" in result.html_path

    @patch("webbrowser.open")
    def test_creates_html_file(
        self, mock_browser, temp_project_dir: Path, sample_audit_data: dict
    ):
        temp_project_dir.mkdir(parents=True)
        create_audit_dir(
            temp_project_dir, "2026-01-29_14-30-45_security", sample_audit_data
        )

        tool = ViewHistoryTool()
        result = tool.execute(project_path=str(temp_project_dir))

        html_path = Path(result.html_path)
        assert html_path.exists()

        content = html_path.read_text()
        assert "<!DOCTYPE html>" in content
        assert "Optix Audit History" in content

    @patch("webbrowser.open")
    def test_returns_empty_when_no_audits(self, mock_browser, temp_project_dir: Path):
        temp_project_dir.mkdir(parents=True)

        tool = ViewHistoryTool()
        result = tool.execute(project_path=str(temp_project_dir))

        assert result.success is True
        assert result.audit_count == 0

    @patch("webbrowser.open")
    def test_opens_browser(
        self, mock_browser, temp_project_dir: Path, sample_audit_data: dict
    ):
        temp_project_dir.mkdir(parents=True)
        create_audit_dir(
            temp_project_dir, "2026-01-29_14-30-45_security", sample_audit_data
        )

        tool = ViewHistoryTool()
        result = tool.execute(project_path=str(temp_project_dir))

        mock_browser.assert_called_once()
        assert result.browser_opened is True

    def test_returns_error_for_nonexistent_path(self):
        tool = ViewHistoryTool()
        result = tool.execute(project_path="/nonexistent/path/12345")

        assert result.success is False
        assert result.error is not None
        assert "does not exist" in result.error

    @patch("webbrowser.open")
    def test_uses_cwd_when_no_path_provided(self, mock_browser, tmp_path: Path):
        import os

        original_cwd = os.getcwd()
        try:
            os.chdir(tmp_path)
            tool = ViewHistoryTool()
            result = tool.execute()

            assert result.success is True
            assert str(tmp_path) in result.html_path
        finally:
            os.chdir(original_cwd)


class TestViewHistoryResponse:
    def test_to_dict_success(self):
        response = ViewHistoryResponse(
            success=True,
            html_path="/path/to/history_viewer.html",
            audit_count=5,
            message="History viewer opened with 5 audits",
            browser_opened=True,
        )

        result = response.to_dict()

        assert result["success"] is True
        assert result["html_path"] == "/path/to/history_viewer.html"
        assert result["audit_count"] == 5
        assert result["message"] == "History viewer opened with 5 audits"
        assert result["browser_opened"] is True
        assert "error" not in result

    def test_to_dict_error(self):
        response = ViewHistoryResponse(
            success=False,
            audit_count=0,
            message="Permission denied",
            browser_opened=False,
            error="Permission denied: /path/to/.optix",
        )

        result = response.to_dict()

        assert result["success"] is False
        assert result["error"] == "Permission denied: /path/to/.optix"
        assert "html_path" not in result
