"""Tests for preflight_checks --fix flag behavior.

All tests are token-less. Run with:
    pytest tests/test_preflight_fix.py -q
"""

import json
import pathlib
import subprocess
import sys
import tempfile

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

PYTHON = str(ROOT / "bin" / "python3") if (ROOT / "bin" / "python3").exists() else sys.executable
PREFLIGHT = str(SCRIPTS / "preflight_checks.py")


def _run_fix(html: str, extra_args=None):
    """Write html to a temp file, run preflight --check-page --fix, return (proc, path)."""
    with tempfile.NamedTemporaryFile(mode="w", suffix=".html", delete=False,
                                    encoding="utf-8") as f:
        f.write(html)
        path = f.name
    args = [PYTHON, PREFLIGHT, "--check-page", "--html-file", path, "--fix", "--json"]
    if extra_args:
        args.extend(extra_args)
    proc = subprocess.run(args, capture_output=True, text=True)
    return proc, path


def _current_content(path):
    return pathlib.Path(path).read_text(encoding="utf-8")


class TestPreflightFix:
    def test_dashes_fixed_and_written_back(self, tmp_path):
        html = "<h2>Key Concepts—Applied</h2><p>The result — passed.</p>"
        p = tmp_path / "page.html"
        p.write_text(html, encoding="utf-8")
        proc = subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-file", str(p), "--fix", "--json"],
            capture_output=True, text=True,
        )
        assert proc.returncode == 0, proc.stderr
        out = json.loads(proc.stdout)
        assert out["fix_counts"]["fix_dashes"] >= 1
        # File was written back — no em dashes remain.
        fixed = p.read_text(encoding="utf-8")
        assert "—" not in fixed
        assert "–" not in fixed

    def test_title_case_fixed(self, tmp_path):
        html = "<h2>The Impact Of Technology</h2><p>Normal body text.</p>"
        p = tmp_path / "page.html"
        p.write_text(html, encoding="utf-8")
        proc = subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-file", str(p), "--fix", "--json"],
            capture_output=True, text=True,
        )
        assert proc.returncode == 0, proc.stderr
        out = json.loads(proc.stdout)
        # title case fixer ran (may or may not change "Of" depending on detection)
        assert "fix_heading_title_case" in out["fix_counts"]

    def test_residual_fixable_count_zero_after_fix(self, tmp_path):
        """After --fix, no fixable issues should remain that the fixer covers."""
        html = "<h2>Key Points—Outlined</h2><p>A—B—C</p>"
        p = tmp_path / "page.html"
        p.write_text(html, encoding="utf-8")
        proc = subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-file", str(p), "--fix", "--json"],
            capture_output=True, text=True,
        )
        assert proc.returncode == 0, proc.stderr
        out = json.loads(proc.stdout)
        assert out["residual_fixable_count"] == 0

    def test_clean_page_zero_changes(self, tmp_path):
        html = "<h2>The Rise of Administrative Law</h2><p>Clean page body.</p>"
        p = tmp_path / "page.html"
        p.write_text(html, encoding="utf-8")
        proc = subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-file", str(p), "--fix", "--json"],
            capture_output=True, text=True,
        )
        assert proc.returncode == 0, proc.stderr
        out = json.loads(proc.stdout)
        assert out["total_fixed"] == 0

    def test_idempotent_double_run(self, tmp_path):
        html = "<h2>Key—Point</h2><p>Test—text.</p>"
        p = tmp_path / "page.html"
        p.write_text(html, encoding="utf-8")
        # First run.
        subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-file", str(p), "--fix"],
            capture_output=True, text=True,
        )
        content_after_1 = p.read_text(encoding="utf-8")
        # Second run.
        proc2 = subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-file", str(p), "--fix", "--json"],
            capture_output=True, text=True,
        )
        out2 = json.loads(proc2.stdout)
        content_after_2 = p.read_text(encoding="utf-8")
        assert out2["total_fixed"] == 0
        assert content_after_1 == content_after_2

    def test_manual_issues_still_reported(self, tmp_path):
        # Slop phrase is a manual (non-fixable) issue.
        html = "<h2>Clean Title</h2><p>Here's the thing: this matters.</p>"
        p = tmp_path / "page.html"
        p.write_text(html, encoding="utf-8")
        proc = subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-file", str(p), "--fix", "--json"],
            capture_output=True, text=True,
        )
        assert proc.returncode == 0, proc.stderr
        out = json.loads(proc.stdout)
        # Slop is advisory/manual — residual_manual_count may be > 0.
        assert "residual_manual_count" in out

    def test_fix_without_html_file_not_required_on_stdin(self, tmp_path):
        # --fix with --html-stdin should not crash (may not write file back).
        html = "<h2>Fix—This</h2>"
        proc = subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-stdin", "--fix", "--json"],
            input=html, capture_output=True, text=True,
        )
        assert proc.returncode == 0, proc.stderr
        out = json.loads(proc.stdout)
        assert "fix_counts" in out

    def test_existing_preflight_check_page_unaffected(self, tmp_path):
        # Without --fix, --check-page still works normally.
        html = "<h2>Clean Title</h2><p>Good body text.</p>"
        p = tmp_path / "page.html"
        p.write_text(html, encoding="utf-8")
        proc = subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-file", str(p), "--json"],
            capture_output=True, text=True,
        )
        assert proc.returncode == 0, proc.stderr
        out = json.loads(proc.stdout)
        # Normal output has "ok" key, not fix_counts.
        assert out.get("ok") is True
        assert "fix_counts" not in out

    def test_lesson5_em_dash_heading_fixed_zero_residual(self, tmp_path):
        """fix_dashes + fix_heading_title_case must produce the exact fixed string
        and leave zero residual title-case issues (BUG 1 regression test)."""
        html = "<h2>Lesson 5 — A Guide To The Markets</h2>"
        p = tmp_path / "page.html"
        p.write_text(html, encoding="utf-8")
        proc = subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-file", str(p), "--fix", "--json"],
            capture_output=True, text=True,
        )
        assert proc.returncode == 0, proc.stderr
        out = json.loads(proc.stdout)
        fixed = p.read_text(encoding="utf-8")
        assert fixed == "<h2>Lesson 5: A Guide to the Markets</h2>", repr(fixed)
        assert out["residual_fixable_count"] == 0

    def test_idempotent_double_run_lesson5(self, tmp_path):
        """Running --fix twice on Lesson 5 heading produces 0 changes the second run."""
        html = "<h2>Lesson 5 — A Guide To The Markets</h2>"
        p = tmp_path / "page.html"
        p.write_text(html, encoding="utf-8")
        subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-file", str(p), "--fix"],
            capture_output=True, text=True,
        )
        proc2 = subprocess.run(
            [PYTHON, PREFLIGHT, "--check-page", "--html-file", str(p), "--fix", "--json"],
            capture_output=True, text=True,
        )
        assert proc2.returncode == 0, proc2.stderr
        out2 = json.loads(proc2.stdout)
        assert out2["total_fixed"] == 0
