use super::*;
use crate::load_fixture_document_from_str;
use rrt_runtime::summary::RuntimeSummary;

const FIXTURE_JSON: &str = r#"
{
  "format_version": 1,
  "fixture_id": "minimal-world-step-smoke",
  "source": {
    "kind": "synthetic",
    "description": "basic milestone parser smoke fixture"
  },
  "state": {
    "calendar": {
      "year": 1830,
      "month_slot": 0,
      "phase_slot": 0,
      "tick_slot": 0
    },
    "world_flags": {
      "sandbox": false
    },
    "companies": [
      {
        "company_id": 1,
        "current_cash": 250000,
        "debt": 0
      }
    ],
    "event_runtime_records": [],
    "service_state": {
      "periodic_boundary_calls": 0,
      "trigger_dispatch_counts": {},
      "total_event_record_services": 0,
      "dirty_rerun_count": 0
    }
  },
  "commands": [
    {
      "kind": "advance_to",
      "calendar": {
        "year": 1830,
        "month_slot": 0,
        "phase_slot": 0,
        "tick_slot": 2
      }
    }
  ],
  "expected_summary": {
    "calendar": {
      "year": 1830,
      "month_slot": 0,
      "phase_slot": 0,
      "tick_slot": 2
    },
    "world_flag_count": 1,
    "company_count": 1,
    "event_runtime_record_count": 0,
    "world_restore_economic_tuning_lane_count": 0,
    "total_company_cash": 250000
  }
}
"#;

#[test]
fn parses_and_validates_fixture() {
    let fixture = load_fixture_document_from_str(FIXTURE_JSON).expect("fixture should parse");
    let report = validate_fixture_document(&fixture);
    assert!(report.valid, "report should be valid: {:?}", report.issues);
    assert_eq!(fixture.state_origin, FixtureStateOrigin::Inline);
}

#[test]
fn compares_expected_summary() {
    let fixture = load_fixture_document_from_str(FIXTURE_JSON).expect("fixture should parse");
    let summary = RuntimeSummary::from_state(&fixture.state);
    let mismatches = fixture.expected_summary.compare(&summary);
    assert_eq!(mismatches.len(), 1);
    assert!(mismatches[0].contains("calendar mismatch"));
}

#[test]
fn compares_expected_state_fragment_recursively() {
    let expected = serde_json::json!({
        "world_flags": {
            "sandbox": false
        },
        "companies": [
            {
                "company_id": 1
            }
        ]
    });
    let actual = serde_json::json!({
        "world_flags": {
            "sandbox": false,
            "runtime.effect_fired": true
        },
        "companies": [
            {
                "company_id": 1,
                "current_cash": 250000
            }
        ]
    });

    let mismatches = compare_expected_state_fragment(&expected, &actual);
    assert!(
        mismatches.is_empty(),
        "unexpected mismatches: {mismatches:?}"
    );
}
