import json
import os
import sys

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

import audit_mlo_drift
import backlog_manager


COURSE_ID = "99993"


def _patch_roots(monkeypatch, tmp_path):
    monkeypatch.setattr(audit_mlo_drift, "PLUGIN_ROOT", tmp_path)
    monkeypatch.setattr(backlog_manager, "get_plugin_root", lambda: str(tmp_path))
    course_dir = tmp_path / "courses" / COURSE_ID
    course_dir.mkdir(parents=True)
    return course_dir


def _write_config(course_dir, objectives):
    config = {
        "course": {"title": "MLO Drift Test"},
        "modules": [{
            "number": 1,
            "objectives": objectives,
        }],
    }
    (course_dir / "course-config.json").write_text(json.dumps(config), encoding="utf-8")


def test_run_audit_writes_report_and_backlog_for_missing_assessment(monkeypatch, tmp_path):
    course_dir = _patch_roots(monkeypatch, tmp_path)
    _write_config(course_dir, [{"id": "M1.1", "text": "Analyze case data."}])
    monkeypatch.setattr(audit_mlo_drift, "fetch_canvas_assessments", lambda _course_id: [])

    report = audit_mlo_drift.run_audit(COURSE_ID)

    assert report["drift_count"] == 1
    assert report["drift_items"][0]["type"] == "missing_assessment"
    report_path = tmp_path / "courses" / COURSE_ID / "reports"
    assert list(report_path.glob("mlo-drift-*.json"))
    backlog_items = backlog_manager.list(COURSE_ID)
    assert backlog_items[0]["type"] == "drift"
    assert backlog_items[0]["mlo_id"] == "M1.1"


def test_detect_drift_flags_lower_bloom_assessment(monkeypatch, tmp_path):
    course_dir = _patch_roots(monkeypatch, tmp_path)
    _write_config(course_dir, [{"id": "M1.2", "text": "Analyze case data."}])
    monkeypatch.setattr(audit_mlo_drift, "fetch_canvas_assessments", lambda _course_id: [{
        "id": "assignment-10",
        "canvas_type": "assignment",
        "title": "Case Data Check",
        "description": "Identify case data.",
        "bloom_level": "Remember",
    }])

    report = audit_mlo_drift.run_audit(COURSE_ID)

    assert report["drift_count"] == 1
    assert report["drift_items"][0]["type"] == "lower_bloom_assessment"
    assert report["drift_items"][0]["assessment_bloom_level"] == "Remember"


def test_detect_drift_allows_equal_or_higher_bloom_assessment(monkeypatch, tmp_path):
    course_dir = _patch_roots(monkeypatch, tmp_path)
    _write_config(course_dir, [{"id": "M1.3", "text": "Apply system models."}])
    monkeypatch.setattr(audit_mlo_drift, "fetch_canvas_assessments", lambda _course_id: [{
        "id": "assignment-11",
        "canvas_type": "assignment",
        "title": "System Models Artifact",
        "description": "Analyze system models.",
        "bloom_level": "Analyze",
    }])

    report = audit_mlo_drift.run_audit(COURSE_ID)

    assert report["drift_count"] == 0
    assert backlog_manager.list(COURSE_ID) == []


def test_load_course_config_falls_back_to_cwd(monkeypatch, tmp_path):
    monkeypatch.setattr(audit_mlo_drift, "PLUGIN_ROOT", tmp_path / "plugin")
    fallback = tmp_path / "course-config.json"
    fallback.write_text(json.dumps({"modules": []}), encoding="utf-8")
    monkeypatch.chdir(tmp_path)

    config, path = audit_mlo_drift.load_course_config(COURSE_ID)

    assert config == {"modules": []}
    assert path == fallback


def test_audit_mlo_drift_api_returns_findings_without_backlog(monkeypatch, tmp_path):
    _patch_roots(monkeypatch, tmp_path)
    config = {
        "modules": [{
            "number": 1,
            "objectives": [{"id": "M1.4", "text": "Analyze case data."}],
        }],
    }

    findings = audit_mlo_drift.audit_mlo_drift(course_config=config, assessments=[])

    assert findings[0]["issue_type"] == "missing_assessment"
    assert backlog_manager.list(COURSE_ID) == []
