import json
import os
import sys

import pytest

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "scripts"))

import audit_remediation_baseline as baseline


def _write_registry(root, courses):
    courses_dir = root / "courses"
    courses_dir.mkdir(parents=True, exist_ok=True)
    (courses_dir / "registry.json").write_text(
        json.dumps({"courses": courses}),
        encoding="utf-8",
    )


def _write_timeline(root, course_id, events):
    course_dir = root / "courses" / str(course_id)
    course_dir.mkdir(parents=True, exist_ok=True)
    path = course_dir / "timeline.jsonl"
    path.write_text(
        "\n".join(json.dumps(event) for event in events) + ("\n" if events else ""),
        encoding="utf-8",
    )
    return path


def _audit(timestamp, object_id="m1-overview", content_type="page"):
    return {
        "timestamp": timestamp,
        "event_type": "audit_completed",
        "course_id": "101",
        "payload": {
            "audit_type": "course_audit",
            "object_id": object_id,
            "content_type": content_type,
            "finding_count": 1,
            "severity_distribution": {"critical": 1, "warning": 0, "info": 0},
        },
    }


def _push(timestamp, object_id="m1-overview", content_type="page"):
    return {
        "timestamp": timestamp,
        "event_type": "push_verified",
        "course_id": "101",
        "payload": {
            "object_id": object_id,
            "content_type": content_type,
            "object_type": content_type,
        },
    }


def test_empty_timeline_has_zero_audits_and_na_rate(tmp_path):
    _write_registry(tmp_path, [{"id": "101", "name": "Empty"}])
    _write_timeline(tmp_path, "101", [])

    summary = baseline.build_summary(tmp_path)
    course = summary["courses"][0]

    assert course["audit_count"] == 0
    assert course["with_remediation_count"] == 0
    assert course["remediation_rate"] is None
    assert course["median_latency_days"] is None


def test_audit_followed_by_same_object_push_within_window_is_remediated(tmp_path):
    _write_registry(tmp_path, [{"id": "101", "name": "Remediated"}])
    _write_timeline(tmp_path, "101", [
        _audit("2026-01-01T00:00:00Z"),
        _push("2026-01-03T12:00:00Z"),
    ])

    course = baseline.build_summary(tmp_path)["courses"][0]

    assert course["audit_count"] == 1
    assert course["with_remediation_count"] == 1
    assert course["remediation_rate"] == 100.0
    assert course["median_latency_days"] == 2.5


def test_audit_without_push_has_zero_remediation_rate(tmp_path):
    _write_registry(tmp_path, [{"id": "101", "name": "Unfixed"}])
    _write_timeline(tmp_path, "101", [
        _audit("2026-01-01T00:00:00Z"),
    ])

    course = baseline.build_summary(tmp_path)["courses"][0]

    assert course["audit_count"] == 1
    assert course["with_remediation_count"] == 0
    assert course["remediation_rate"] == 0.0
    assert course["median_latency_days"] is None


def test_push_of_different_object_does_not_remediate_audit(tmp_path):
    _write_registry(tmp_path, [{"id": "101", "name": "Mismatch"}])
    _write_timeline(tmp_path, "101", [
        _audit("2026-01-01T00:00:00Z", object_id="m1-overview"),
        _push("2026-01-02T00:00:00Z", object_id="m2-overview"),
    ])

    course = baseline.build_summary(tmp_path)["courses"][0]

    assert course["audit_count"] == 1
    assert course["with_remediation_count"] == 0
    assert course["remediation_rate"] == 0.0
    assert course["audits"][0]["latency_days"] is None


def test_mixed_multi_course_aggregation(tmp_path):
    _write_registry(tmp_path, [
        {"id": "101", "name": "One"},
        {"id": "202", "name": "Two"},
    ])
    _write_timeline(tmp_path, "101", [
        _audit("2026-01-01T00:00:00Z"),
        _push("2026-01-06T00:00:00Z"),
    ])
    _write_timeline(tmp_path, "202", [
        _audit("2026-01-01T00:00:00Z", object_id="m2-overview"),
    ])

    summary = baseline.build_summary(tmp_path)

    assert summary["program"]["total_audits"] == 2
    assert summary["program"]["with_remediation_count"] == 1
    assert summary["program"]["weighted_remediation_rate"] == 50.0
    assert summary["program"]["median_latency_days"] == 5.0


def test_missing_timeline_is_graceful_skip(tmp_path):
    _write_registry(tmp_path, [{"id": "101", "name": "Missing Timeline"}])

    summary = baseline.build_summary(tmp_path)
    course = summary["courses"][0]

    assert course["skipped"] is True
    assert course["audit_count"] == 0
    assert course["note"] == "timeline.jsonl not found"


def test_missing_registry_returns_friendly_error(tmp_path, capsys):
    exit_code = baseline.main([], root=tmp_path)

    captured = capsys.readouterr()
    assert exit_code == 1
    assert "courses/registry.json not found" in captured.err
