#!/usr/bin/env python3
"""Tests for pr_backlog_triage.py — issue #658."""
import json
import sys
from pathlib import Path

import pytest

sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
from pr_backlog_triage import (
    categorize_pr,
    extract_refs,
    find_duplicates,
    find_stale,
    format_report,
    format_json,
)


class TestCategorize:
    def test_training_data(self):
        pr = {"title": "feat: 500 emotional weather pairs (#603)"}
        assert categorize_pr(pr) == "training_data"

    def test_scene_description(self):
        pr = {"title": "feat: 100 jazz scene descriptions (#612)"}
        assert categorize_pr(pr) == "training_data"

    def test_bug_fix(self):
        pr = {"title": "fix: broken import in cli.py"}
        assert categorize_pr(pr) == "bug_fix"

    def test_feature(self):
        pr = {"title": "feat: add token budget tracker"}
        assert categorize_pr(pr) == "feature"

    def test_docs(self):
        pr = {"title": "docs: update README with new config format"}
        assert categorize_pr(pr) == "docs"

    def test_ops(self):
        pr = {"title": "ops: deploy config to Ezra VPS"}
        assert categorize_pr(pr) == "ops"

    def test_other(self):
        pr = {"title": "chore: cleanup whitespace"}
        assert categorize_pr(pr) == "other"

    def test_case_insensitive(self):
        pr = {"title": "FIX: resolve import error"}
        assert categorize_pr(pr) == "bug_fix"

    def test_empty_title(self):
        pr = {"title": ""}
        assert categorize_pr(pr) == "other"

    def test_none_title(self):
        pr = {}
        assert categorize_pr(pr) == "other"


class TestExtractRefs:
    def test_single_ref(self):
        pr = {"title": "Fix #123", "body": "Closes #123"}
        assert extract_refs(pr) == [123]

    def test_multiple_refs(self):
        pr = {"title": "Fix #123", "body": "Related to #456 and #789"}
        assert extract_refs(pr) == [123, 456, 789]

    def test_deduplication(self):
        pr = {"title": "#100", "body": "Fixes #100"}
        assert extract_refs(pr) == [100]

    def test_no_refs(self):
        pr = {"title": "No issue here", "body": "Just a PR"}
        assert extract_refs(pr) == []

    def test_empty_body(self):
        pr = {"title": "Fix #42", "body": None}
        assert extract_refs(pr) == [42]


class TestFindDuplicates:
    def test_no_duplicates(self):
        prs = [
            {"number": 1, "title": "Fix #10", "body": ""},
            {"number": 2, "title": "Fix #11", "body": ""},
        ]
        assert find_duplicates(prs) == {}

    def test_duplicates_found(self):
        prs = [
            {"number": 1, "title": "Fix #10", "body": ""},
            {"number": 2, "title": "Also fix #10", "body": ""},
        ]
        dupes = find_duplicates(prs)
        assert 10 in dupes
        assert dupes[10] == [1, 2]

    def test_triple_duplicate(self):
        prs = [
            {"number": 1, "title": "#42", "body": ""},
            {"number": 2, "title": "#42", "body": ""},
            {"number": 3, "title": "#42", "body": ""},
        ]
        dupes = find_duplicates(prs)
        assert len(dupes[42]) == 3


class TestFindStale:
    def test_no_stale(self):
        prs = [{"number": 1, "title": "Fix #10", "body": ""}]
        closed = set()
        assert find_stale(prs, closed) == []

    def test_stale_found(self):
        prs = [{"number": 1, "title": "Fix #10", "body": ""}]
        closed = {10}
        stale = find_stale(prs, closed)
        assert len(stale) == 1
        assert stale[0]["pr"] == 1
        assert stale[0]["closed_refs"] == [10]

    def test_mixed_refs(self):
        prs = [{"number": 1, "title": "Fix #10 and #20", "body": ""}]
        closed = {10}
        stale = find_stale(prs, closed)
        assert stale[0]["closed_refs"] == [10]


class TestFormatReport:
    def test_basic_report(self):
        analysis = {
            "repo": "test/repo",
            "total_open": 5,
            "categories": {"feature": 3, "bug_fix": 2},
            "category_details": {
                "feature": [
                    {"number": 1, "title": "feat: x", "refs": [10], "head": "f1",
                     "additions": 10, "deletions": 5, "changed_files": 2, "created": "2026-04-01"}
                ],
                "bug_fix": [],
            },
            "duplicates": {},
            "stale_prs": [],
            "closed_issues_checked": 100,
        }
        report = format_report(analysis)
        assert "test/repo" in report
        assert "5" in report
        assert "feature" in report

    def test_stale_in_report(self):
        analysis = {
            "repo": "test/repo",
            "total_open": 1,
            "categories": {"feature": 1},
            "category_details": {},
            "duplicates": {},
            "stale_prs": [{"pr": 5, "closed_refs": [10]}],
            "closed_issues_checked": 50,
        }
        report = format_report(analysis)
        assert "#5" in report
        assert "#10" in report

    def test_duplicates_in_report(self):
        analysis = {
            "repo": "test/repo",
            "total_open": 2,
            "categories": {"bug_fix": 2},
            "category_details": {},
            "duplicates": {42: [1, 2]},
            "stale_prs": [],
            "closed_issues_checked": 0,
        }
        report = format_report(analysis)
        assert "Duplicate" in report
        assert "#42" in report


class TestFormatJson:
    def test_valid_json(self):
        analysis = {"repo": "test", "total_open": 0}
        out = format_json(analysis)
        parsed = json.loads(out)
        assert parsed["repo"] == "test"
