//! v1 retained for back-compat with consumers pinned before v2; new code
//! should use export_completed_data_v2.
//!
//! FC-46: this integration test exists solely to provide event-emission
//! coverage for `dev.cellos.events.cell.export.v1.completed`. The v1
//! constructor (`export_completed_data_v1`) is still `pub` and re-exported
//! from `cellos_core` because downstream consumers may have pinned to the
//! v1 wire format prior to the v2 introduction (which moved
//! `bytesWritten`/`destinationRelative` into a structured `receipt`).
//! Removing v1 is not safe until those consumers are migrated, so the
//! constructor stays and this test exercises it to keep the FC-46
//! event-emission-coverage gate green.
//!
//! Schema: `contracts/schemas/cell-export-completed-v1.schema.json`.

use cellos_core::{export_completed_data_v1, ExecutionCellDocument};

/// Build a sample spec from the checked-in valid example, call the v1
/// constructor, and assert the v1 wire shape matches the v1 schema /
/// fixture (`contracts/examples/cell-export-v1-completed-data.valid.json`).
#[test]
fn export_completed_v1_legacy_wire_shape() {
    let raw = include_str!("../../../contracts/examples/execution-cell-minimal.valid.json");
    let doc: ExecutionCellDocument = serde_json::from_str(raw).expect("parse minimal spec");

    // Mirror the checked-in v1 fixture so this test stays anchored to the
    // schema's documented shape.
    let data = export_completed_data_v1(
        &doc.spec,
        "host-cell-demo",
        Some("run-001"),
        "build-log",
        1024,
        "demo-cell-001/build-log",
    )
    .expect("serialize v1 export-completed data");

    // v1 envelope: flat `bytesWritten` + `destinationRelative` (no nested
    // `receipt`/`target` — those are v2 additions).
    assert_eq!(data["cellId"], "host-cell-demo");
    assert_eq!(data["specId"], "demo-cell-001");
    assert_eq!(data["runId"], "run-001");
    assert_eq!(data["artifactName"], "build-log");
    assert_eq!(data["bytesWritten"], 1024);
    assert_eq!(data["destinationRelative"], "demo-cell-001/build-log");

    // v1 must NOT carry v2-only fields.
    assert!(
        data.get("receipt").is_none(),
        "v1 envelope must not contain v2 `receipt` field"
    );
    assert!(
        data.get("target").is_none(),
        "v1 envelope must not contain v2 `target` field"
    );
    assert!(
        data.get("provenance").is_none(),
        "v1 envelope must not contain v2 `provenance` field"
    );

    // The minimal spec has no correlation set, so the optional field is
    // omitted from the JSON (consistent with v2 behaviour).
    assert!(data.get("correlation").is_none());
}

/// `runId` is optional per the v1 schema; verify omission produces a
/// payload without the key (rather than a JSON `null`), matching the
/// schema's `additionalProperties: false` constraint.
#[test]
fn export_completed_v1_omits_optional_run_id() {
    let raw = include_str!("../../../contracts/examples/execution-cell-minimal.valid.json");
    let doc: ExecutionCellDocument = serde_json::from_str(raw).expect("parse minimal spec");

    let data = export_completed_data_v1(
        &doc.spec,
        "host-cell-demo",
        None,
        "build-log",
        0,
        "demo-cell-001/build-log",
    )
    .expect("serialize v1 export-completed data");

    assert!(
        data.get("runId").is_none(),
        "optional runId should be omitted, not serialized as null"
    );
    assert_eq!(data["bytesWritten"], 0);
}

/// Anchor the test to the checked-in v1 example fixture so any drift in
/// the v1 wire format is caught loudly.
#[test]
fn export_completed_v1_matches_checked_in_fixture() {
    let raw = include_str!("../../../contracts/examples/execution-cell-minimal.valid.json");
    let doc: ExecutionCellDocument = serde_json::from_str(raw).expect("parse minimal spec");

    let expected: serde_json::Value = serde_json::from_str(include_str!(
        "../../../contracts/examples/cell-export-v1-completed-data.valid.json"
    ))
    .expect("parse v1 fixture");

    let data = export_completed_data_v1(
        &doc.spec,
        "host-cell-demo",
        Some("run-001"),
        "build-log",
        1024,
        "demo-cell-001/build-log",
    )
    .expect("serialize v1 export-completed data");

    assert_eq!(data, expected);
}
