//! p10-1A-1 Task 13: regression — the 5 original Citation variants
//! (Line, Page, Region, Caption, Time) serialize byte-identically to
//! pre-Task-1 form.  No spurious `code`, `line_start`, or `symbol` keys
//! must leak into these variants.

use kebab_core::{Citation, WorkspacePath};

#[test]
fn line_variant_serialization_unchanged() {
    let c = Citation::Line {
        path: WorkspacePath::new("a.md".into()).unwrap(),
        start: 1,
        end: 2,
        section: Some("§14".into()),
    };
    let v = serde_json::to_value(&c).unwrap();
    assert_eq!(v["kind"], "line");
    assert_eq!(v["start"], 1);
    assert_eq!(v["end"], 2);
    assert_eq!(v["section"], "§14");
    // Must not bleed Code-variant keys.
    assert!(
        v.get("line_start").is_none(),
        "line_start must be absent: {v}"
    );
    assert!(v.get("symbol").is_none(), "symbol must be absent: {v}");
    assert!(v.get("code").is_none(), "code must be absent: {v}");
}

#[test]
fn line_variant_null_section_omitted() {
    let c = Citation::Line {
        path: WorkspacePath::new("b.md".into()).unwrap(),
        start: 5,
        end: 10,
        section: None,
    };
    let v = serde_json::to_value(&c).unwrap();
    assert_eq!(v["kind"], "line");
    // `section` with None should be omitted (skip_serializing_if = is_none).
    assert!(v.get("section").is_none() || v["section"].is_null());
}

#[test]
fn page_variant_serialization_unchanged() {
    let c = Citation::Page {
        path: WorkspacePath::new("a.pdf".into()).unwrap(),
        page: 13,
        section: None,
    };
    let v = serde_json::to_value(&c).unwrap();
    assert_eq!(v["kind"], "page");
    assert_eq!(v["page"], 13);
    assert!(
        v.get("line_start").is_none(),
        "line_start must be absent: {v}"
    );
    assert!(v.get("symbol").is_none(), "symbol must be absent: {v}");
}

#[test]
fn region_variant_serialization_unchanged() {
    let c = Citation::Region {
        path: WorkspacePath::new("img.png".into()).unwrap(),
        x: 10,
        y: 20,
        w: 100,
        h: 200,
    };
    let v = serde_json::to_value(&c).unwrap();
    assert_eq!(v["kind"], "region");
    assert_eq!(v["x"], 10);
    assert_eq!(v["y"], 20);
    assert_eq!(v["w"], 100);
    assert_eq!(v["h"], 200);
    assert!(
        v.get("line_start").is_none(),
        "line_start must be absent: {v}"
    );
}

#[test]
fn caption_variant_serialization_unchanged() {
    let c = Citation::Caption {
        path: WorkspacePath::new("a.png".into()).unwrap(),
        model: "qwen2.5-vl:7b".into(),
    };
    let v = serde_json::to_value(&c).unwrap();
    assert_eq!(v["kind"], "caption");
    assert_eq!(v["model"], "qwen2.5-vl:7b");
    assert!(
        v.get("line_start").is_none(),
        "line_start must be absent: {v}"
    );
}

#[test]
fn time_variant_serialization_unchanged() {
    let c = Citation::Time {
        path: WorkspacePath::new("audio.mp3".into()).unwrap(),
        start_ms: 1000,
        end_ms: 5000,
        speaker: Some("Alice".into()),
    };
    let v = serde_json::to_value(&c).unwrap();
    assert_eq!(v["kind"], "time");
    assert_eq!(v["start_ms"], 1000);
    assert_eq!(v["end_ms"], 5000);
    assert_eq!(v["speaker"], "Alice");
    assert!(
        v.get("line_start").is_none(),
        "line_start must be absent: {v}"
    );
    assert!(v.get("symbol").is_none(), "symbol must be absent: {v}");
}
