#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>
#include <string_view>

#include "diagnostics/null_diagnostic_session.h"

namespace {

void Expect(bool condition, std::string_view message) {
  if (!condition) {
    std::cerr << "FAILED: " << message << "\n";
    std::exit(1);
  }
}

std::string ReadText(const std::filesystem::path& path) {
  std::ifstream file(path, std::ios::binary);
  return std::string((std::istreambuf_iterator<char>(file)),
                     std::istreambuf_iterator<char>());
}

void TestNullSessionProducesStatsAndEvents() {
  aptt::PlaybackConfig config;
  config.duration_ms = 100;
  config.format.sample_rate_hz = 48000;

  const auto session = aptt::RunNullDiagnosticSession(config);
  Expect(session.result.ok, "session succeeds");
  Expect(session.stats.frames_generated == 4800, "session generated expected frames");
  Expect(session.stats.underrun_count == 0, "session has no underruns");
  Expect(session.events.size() >= 8, "session records lifecycle events");
  Expect(!session.bundle_directory.has_value(), "bundle is optional");
}

void TestNullSessionWritesBundle() {
  const std::filesystem::path out =
      std::filesystem::current_path() / "null_session_bundle_output";
  std::filesystem::remove_all(out);

  aptt::PlaybackConfig config;
  config.duration_ms = 50;

  const auto session = aptt::RunNullDiagnosticSession(config, out);
  Expect(session.result.ok, "session with bundle succeeds");
  Expect(session.bundle_directory == out, "bundle path is reported");
  Expect(std::filesystem::exists(out / "config.json"), "config exists");
  Expect(std::filesystem::exists(out / "playback.jsonl"), "playback exists");
  Expect(std::filesystem::exists(out / "realtime.csv"), "realtime exists");
  Expect(ReadText(out / "playback.jsonl").find("session_summary") != std::string::npos,
         "playback contains session summary");
  Expect(ReadText(out / "summary.txt").find("frames_generated") != std::string::npos,
         "summary contains stats");
}

}  // namespace

int main() {
  TestNullSessionProducesStatsAndEvents();
  TestNullSessionWritesBundle();

  std::cout << "null diagnostic session tests passed\n";
  return 0;
}
