/**
 * Layer-3 NMEA replay regression test.
 *
 * Fixture: examples/real_track_data_debug/gps_race_data_praga_laps.h
 *   Orlando Kart Center, two laps, Praga Dark with blown Tillotson motor.
 *
 * Golden times (current library output, captured 2026-05-21):
 *   LAP 1: 62726 ms — linear == catmull
 *   LAP 2: 61319 ms — linear == catmull
 *
 * Fixture-header values (LAP 1 LINEAR 62727, LAP 2 LINEAR 61317) drift by
 * 1-2 ms — minor linear-interpolation refinement since original capture.
 * No MyLaps or Catmull-Rom baseline was recorded for this fixture; we
 * exercise both modes here for code-path coverage, and assert they agree
 * (per CLAUDE.md known-issue #1: spline is scoped to lat/lng only, so
 * lap times are mode-independent).
 */

#include "test_runner.h"
#include "replay_runner.h"
#include "../examples/real_track_data_debug/gps_race_data_praga_laps.h"

static const int num_gps_logs = sizeof(gps_logs) / sizeof(gps_logs[0]);

static ReplayConfig makeCfg(bool catmull) {
  ReplayConfig c;
  c.sfA_lat = 28.41270817056385; c.sfA_lng = -81.37973266418031;
  c.sfB_lat = 28.41273038679321; c.sfB_lng = -81.37957048753776;
  c.useCatmullRom = catmull;
  return c;
}

void test_linear_completes_two_laps() {
  ReplayResult r = runNmeaReplay(gps_logs, num_gps_logs, makeCfg(false));
  EXPECT_EQ((int)r.lapTimes.size(), 2);
}

void test_linear_lap1_matches_pinned_golden() {
  ReplayResult r = runNmeaReplay(gps_logs, num_gps_logs, makeCfg(false));
  EXPECT_TRUE(r.lapTimes.size() >= 1);
  if (r.lapTimes.size() >= 1) EXPECT_NEAR(r.lapTimes[0], 62726UL, 10.0);
}

void test_linear_lap2_matches_pinned_golden() {
  ReplayResult r = runNmeaReplay(gps_logs, num_gps_logs, makeCfg(false));
  EXPECT_TRUE(r.lapTimes.size() >= 2);
  if (r.lapTimes.size() >= 2) EXPECT_NEAR(r.lapTimes[1], 61319UL, 10.0);
}

void test_catmull_lap_times_match_linear() {
  ReplayResult lin = runNmeaReplay(gps_logs, num_gps_logs, makeCfg(false));
  ReplayResult cat = runNmeaReplay(gps_logs, num_gps_logs, makeCfg(true));
  EXPECT_TRUE(lin.lapTimes.size() >= 2 && cat.lapTimes.size() >= 2);
  if (lin.lapTimes.size() >= 2 && cat.lapTimes.size() >= 2) {
    EXPECT_EQ(cat.lapTimes[0], lin.lapTimes[0]);
    EXPECT_EQ(cat.lapTimes[1], lin.lapTimes[1]);
  }
}

int main() {
  printf("=== NMEA replay: OKC praga two laps (gps_race_data_praga_laps.h) ===\n");

  RUN_TEST(linear_completes_two_laps);
  RUN_TEST(linear_lap1_matches_pinned_golden);
  RUN_TEST(linear_lap2_matches_pinned_golden);
  RUN_TEST(catmull_lap_times_match_linear);

  TEST_SUMMARY();
}
