"""Tests for web UI worktree hygiene dashboard (#432)."""
import json
import sys
import tempfile
import unittest
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from starlette.testclient import TestClient

from webui.app import create_app
from webui.worktree_scanner import (
    classify_entry,
    load_hygiene_snapshot,
    parse_worktree_list_porcelain,
    snapshot_to_dict,
)


class TestWorktreeScanner(unittest.TestCase):
    def test_parse_worktree_porcelain(self):
        porcelain = (
            "worktree /repo/branches/feat-issue-1-foo\n"
            "HEAD abcdef0123456789\n"
            "branch refs/heads/feat/issue-1-foo\n"
            "\n"
        )
        entries = parse_worktree_list_porcelain(porcelain)
        self.assertEqual(len(entries), 1)
        self.assertEqual(entries[0]["branch"], "feat/issue-1-foo")

    def test_classify_active_pr(self):
        classification, _ = classify_entry(
            rel_path="branches/feat-issue-99-demo",
            worktree_record={"branch": "feat/issue-99-demo"},
            state={"exists": True, "clean": True, "dirty_files": []},
            open_pr_branches={"feat/issue-99-demo"},
            active_lock_branch=None,
        )
        self.assertEqual(classification, "active-pr")

    def test_classify_dirty(self):
        classification, _ = classify_entry(
            rel_path="branches/feat-issue-2-bar",
            worktree_record={"branch": "feat/issue-2-bar"},
            state={"exists": True, "clean": False, "dirty_files": ["webui/app.py"]},
            open_pr_branches=set(),
            active_lock_branch=None,
        )
        self.assertEqual(classification, "dirty")

    def test_missing_lock_worktree_anomaly(self):
        with tempfile.TemporaryDirectory() as tmp:
            branches = Path(tmp) / "branches" / "other-worktree"
            branches.mkdir(parents=True)
            lock_path = Path(tmp) / "lock.json"
            lock_path.write_text(
                json.dumps({
                    "issue_number": 432,
                    "branch_name": "feat/issue-432-worktree-hygiene",
                    "worktree_path": str(Path(tmp) / "branches" / "missing-tree"),
                }),
                encoding="utf-8",
            )
            snapshot = load_hygiene_snapshot(
                project_root=tmp,
                worktree_porcelain="",
                open_pr_branches=set(),
                issue_lock_path=str(lock_path),
            )
            self.assertTrue(snapshot.anomalies)
            self.assertIn("Missing preserved worktree", snapshot.anomalies[0])

    def test_snapshot_to_dict(self):
        with tempfile.TemporaryDirectory() as tmp:
            (Path(tmp) / "branches").mkdir()
            snapshot = load_hygiene_snapshot(
                project_root=tmp,
                worktree_porcelain="",
                open_pr_branches=set(),
                issue_lock_path=str(Path(tmp) / "no-lock.json"),
            )
            data = snapshot_to_dict(snapshot)
            self.assertIn("entries", data)
            self.assertIn("cleanup_prompt", data)


class TestWorktreeRoutes(unittest.TestCase):
    def setUp(self):
        self.client = TestClient(create_app())

    def test_worktrees_page_renders(self):
        response = self.client.get("/worktrees")
        self.assertEqual(response.status_code, 200)
        self.assertIn("Worktree hygiene", response.text)
        self.assertIn("Canonical cleanup prompt", response.text)
        self.assertIn("Copy cleanup prompt", response.text)
        self.assertNotIn("child issue", response.text.lower())

    def test_api_worktrees_json(self):
        response = self.client.get("/api/worktrees")
        self.assertEqual(response.status_code, 200)
        data = response.json()
        self.assertIn("entries", data)
        self.assertIn("cleanup_prompt", data)
        self.assertIn("anomalies", data)

    def test_nav_includes_worktrees(self):
        self.assertIn('href="/worktrees"', self.client.get("/").text)


if __name__ == "__main__":
    unittest.main()