#include <cstdlib>
#include <iostream>
#include <string_view>

#include "backends/mme_device_discovery.h"
#include "backends/mme_pcm_backend.h"

namespace {

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

aptt::PlaybackConfig MakeMmePcmConfig() {
  aptt::PlaybackConfig config;
  config.backend = aptt::BackendApi::kMme;
  config.device.backend = aptt::BackendApi::kMme;
  config.device.display_name = "Fixture waveOut";
  config.device.stable_id = "mme:waveout:1";
  config.device.driver_name = "MME/waveOut";
  config.device.is_known_problem_device = true;
  config.format = aptt::MmePcmCandidate(48000, aptt::SampleType::kInt16, 2);
  config.duration_ms = 1000;
  config.hold_mode = aptt::HoldMode::kKeepWarmAfterStop;
  config.release_cooldown_ms = 1000;
  return config;
}

void TestMmePolicyDefaultsAreConservative() {
  const auto config = MakeMmePcmConfig();
  const auto policy = aptt::MakeMmePcmPolicy(config);

  Expect(policy.requires_explicit_device, "explicit device is required");
  Expect(policy.keep_warm_after_signal, "keep-warm is the default policy");
  Expect(!policy.release_after_drain, "release after drain is not default");
  Expect(!policy.uses_reset_on_normal_stop, "normal stop does not use reset");
  Expect(policy.reset_is_fault_only, "reset is fault-only");
  Expect(policy.buffer_count >= 2, "prepared buffer queue has depth");
  Expect(policy.buffer_duration_ms > 0, "buffer duration is explicit");
}

void TestMmeFormatGateAcceptsRenderablePcmFormats() {
  auto config = MakeMmePcmConfig();
  Expect(aptt::IsMmePcmPlaybackFormat(config.format),
         "int16 PCM is accepted");

  config.format = aptt::MmePcmCandidate(
      48000,
      aptt::SampleType::kInt24Packed,
      2);
  Expect(aptt::IsMmePcmPlaybackFormat(config.format),
         "packed 24-bit PCM is accepted");

  config.format = aptt::MmePcmCandidate(
      48000,
      aptt::SampleType::kInt24In32,
      2);
  Expect(aptt::IsMmePcmPlaybackFormat(config.format),
         "24-in-32 PCM is accepted");

  config.format.sample_type = aptt::SampleType::kFloat32;
  config.format.valid_bits_per_sample = 32;
  config.format.container_bits_per_sample = 32;
  Expect(aptt::IsMmePcmPlaybackFormat(config.format),
         "float32 PCM is accepted");

  config.format = aptt::MmePcmCandidate(
      48000,
      aptt::SampleType::kInt32,
      2);
  Expect(aptt::IsMmePcmPlaybackFormat(config.format),
         "int32 PCM is accepted");

  config.format.signal_mode = aptt::SignalMode::kDop;
  Expect(!aptt::IsMmePcmPlaybackFormat(config.format),
         "DoP is outside the MME PCM task");
}

void TestMmeInitializeRequiresExplicitDeviceBeforeApiUse() {
  auto config = MakeMmePcmConfig();
  config.device.stable_id.clear();

  aptt::MmePcmBackend backend;
  const auto result = backend.initialize(config);

  Expect(!result.ok, "initialize without MME device fails");
  Expect(backend.lifecycle_state() == aptt::DeviceLifecycleState::kDiscovered,
         "missing MME device fails before reserving a device");
  Expect(backend.diagnostic_events().empty(),
         "missing MME device emits no real-device lifecycle events");
}

void TestMmeResetRequiresOpenDevice() {
  aptt::MmePcmBackend backend;
  const auto result = backend.reset();

  Expect(!result.ok, "reset without open device fails");
  Expect(result.error.message.find("not open") != std::string::npos,
         "reset failure explains no open device");
}

}  // namespace

int main() {
  TestMmePolicyDefaultsAreConservative();
  TestMmeFormatGateAcceptsRenderablePcmFormats();
  TestMmeInitializeRequiresExplicitDeviceBeforeApiUse();
  TestMmeResetRequiresOpenDevice();

  std::cout << "MME PCM backend tests passed\n";
  return 0;
}
