"""Tests for scripts/apa_title_case.py — the APA title-case linter."""

import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
SCRIPTS_DIR = ROOT / "scripts"
sys.path.insert(0, str(SCRIPTS_DIR))

import apa_title_case as atc  # noqa: E402


# --- PASS: clean titles -----------------------------------------------------

PASS_TITLES = [
    "Use the Weekly Homework Standards",
    "Mid-Project Check-In (Week 5)",
    "Avg Peer Rating Received (0-10)",
    "Quality of Contribution",
    "How It Works",
]


def test_pass_titles_have_no_issues():
    for title in PASS_TITLES:
        assert atc.check_title(title) == [], f"unexpected issues for {title!r}"


# --- FAIL: titles with violations -------------------------------------------

def test_fail_group_project_score():
    issues = atc.check_title("Group project score")
    joined = " ".join(issues)
    assert "'project' should be capitalized" in issues
    assert "'score' should be capitalized" in issues


def test_fail_what_exists_now():
    issues = atc.check_title("What exists now")
    assert "'exists' should be capitalized" in issues
    assert "'now' should be capitalized" in issues


def test_fail_lowercase_how_it_works():
    issues = atc.check_title("how it works")
    assert "'how' should be capitalized" in issues
    assert "'It'" not in " ".join(issues)  # 'it' flagged as lowercase, not cap
    assert "'it' should be capitalized" in issues
    assert "'works' should be capitalized" in issues


def test_fail_minor_word_capitalized_midtitle():
    # "The" is a minor word (<=3 letters) and must be lowercase mid-title.
    issues = atc.check_title("Use The Weekly Homework Standards")
    assert "'The' should be lowercase" in issues


# --- Edge cases -------------------------------------------------------------

def test_minor_word_first_is_capitalized():
    # "Of" leads the title -> first word always capitalized, no issue.
    assert atc.check_title("Of Mice and Men") == []


def test_last_word_always_capitalized():
    # A minor word as the last word must be capitalized.
    issues = atc.check_title("What Is It up")
    assert "'up' should be capitalized" in issues


def test_first_word_after_colon_capitalized():
    # Minor word right after a colon must be capitalized.
    issues = atc.check_title("The Report: on the Findings")
    assert "'on' should be capitalized" in issues


def test_hyphenated_both_parts_capitalized():
    issues = atc.check_title("Mid-project Check-In")
    assert "'project' should be capitalized" in issues


def test_hyphenated_clean():
    assert atc.check_title("Mid-Project Check-In") == []


def test_non_alpha_tokens_ignored():
    # Numbers, "(50", "%)", "&" must not raise or flag.
    assert atc.check_title("Score 50% & Up (0-10)") == []


def test_acronyms_preserved():
    assert atc.check_title("Aligned MLOs and CLOs") == []


def test_empty_and_whitespace():
    assert atc.check_title("") == []
    assert atc.check_title("   ") == []
    assert atc.check_title(None) == []


# --- lint_html --------------------------------------------------------------

def test_lint_html_checks_headings_only():
    html = (
        "<h2>Group project score</h2>"
        "<p>this is body prose not a title</p>"
        "<td>data cell not linted</td>"
        "<summary>How It Works</summary>"
    )
    results = atc.lint_html(html)
    # h2 has a violation; p/td not linted; summary is clean.
    contexts = [c for (c, _t, _i) in results]
    assert "h2" in contexts
    assert "p" not in contexts
    assert "td" not in contexts
    # summary clean -> not in results
    titles = [t for (_c, t, _i) in results]
    assert "How It Works" not in titles


def test_lint_html_no_headings_returns_empty():
    assert atc.lint_html("<p>just prose here</p>") == []
    assert atc.lint_html("") == []


# --- CLI --------------------------------------------------------------------

def test_cli_text_clean_exit_zero():
    assert atc.main(["--text", "How It Works"]) == 0


def test_cli_text_violation_exit_one():
    assert atc.main(["--text", "Group project score"]) == 1


def test_cli_file_no_headings_exit_zero(tmp_path):
    f = tmp_path / "page.html"
    f.write_text("<p>just prose</p>", encoding="utf-8")
    assert atc.main(["--file", str(f)]) == 0


def test_cli_empty_file_exit_zero(tmp_path):
    f = tmp_path / "empty.html"
    f.write_text("", encoding="utf-8")
    assert atc.main(["--file", str(f)]) == 0
