#include <cstdlib>
#include <cstdint>
#include <iostream>
#include <string_view>
#include <vector>

#include "backends/wasapi_error.h"
#include "backends/wasapi_exclusive_pcm_backend.h"
#include "core/dop_generator.h"

namespace {

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

aptt::PlaybackConfig MakeExclusivePcmConfig() {
  aptt::PlaybackConfig config;
  config.backend = aptt::BackendApi::kWasapiExclusive;
  config.device.backend = aptt::BackendApi::kWasapiExclusive;
  config.device.display_name = "Fixture WASAPI endpoint";
  config.device.stable_id = "fixture-endpoint";
  config.device.driver_name = "WASAPI/Core Audio";
  config.device.is_known_problem_device = true;
  config.format.signal_mode = aptt::SignalMode::kPcm;
  config.format.sample_rate_hz = 48000;
  config.format.sample_type = aptt::SampleType::kFloat32;
  config.format.valid_bits_per_sample = 32;
  config.format.container_bits_per_sample = 32;
  config.format.channels.channel_count = 2;
  config.format.channels.channel_mask = 3;
  config.duration_ms = 1000;
  config.hold_mode = aptt::HoldMode::kKeepWarmAfterStop;
  config.release_cooldown_ms = 1000;
  return config;
}

void TestExclusivePolicyRequiresExactSupport() {
  const auto config = MakeExclusivePcmConfig();
  const auto policy = aptt::MakeWasapiExclusivePcmPolicy(config);

  Expect(policy.requires_explicit_endpoint, "explicit endpoint is required");
  Expect(policy.requires_exact_format_support,
         "exact IsFormatSupported success is required");
  Expect(policy.keep_warm_after_signal, "keep-warm is the default policy");
  Expect(!policy.uses_reset_on_normal_stop, "normal stop does not use Reset");
  Expect(!policy.uses_shared_fallback, "shared fallback is disabled");
  Expect(!policy.uses_format_fallback, "format fallback is disabled");
  Expect(policy.event_callback_enabled,
         "exclusive event callback rendering is enabled by default");
  Expect(policy.alignment_retry_enabled,
         "exclusive event-buffer alignment retry is enabled by default");
  Expect(policy.buffer_duration_ms == policy.periodicity_ms,
         "event-driven exclusive buffer duration and periodicity are equal");
  Expect(policy.event_wait_timeout_ms == 2000,
         "exclusive event wait timeout is preserved");
}

void TestExclusivePolicySupportsTimerDrivenPeriodDefaults() {
  auto config = MakeExclusivePcmConfig();
  config.wasapi_exclusive_event_callback_enabled = false;
  config.wasapi_exclusive_periodicity_ms = 0;
  config.wasapi_exclusive_alignment_retry_enabled = false;
  config.wasapi_exclusive_event_timeout_ms = 3210;

  const auto policy = aptt::MakeWasapiExclusivePcmPolicy(config);

  Expect(!policy.event_callback_enabled,
         "timer-driven exclusive mode can be requested");
  Expect(policy.periodicity_ms == 0,
         "timer-driven exclusive mode can request the device default period");
  Expect(!policy.alignment_retry_enabled,
         "alignment retry can be disabled for timer-driven diagnostics");
  Expect(policy.event_wait_timeout_ms == 3210,
         "event timeout is retained even when event mode is disabled");
}

aptt::FormatDescriptor MakePcmFormat(aptt::SampleType sample_type,
                                     std::uint32_t valid_bits,
                                     std::uint32_t container_bits) {
  auto config = MakeExclusivePcmConfig();
  config.format.sample_type = sample_type;
  config.format.valid_bits_per_sample = valid_bits;
  config.format.container_bits_per_sample = container_bits;
  return config.format;
}

void TestExclusiveFormatGateAcceptsSupportedPcmContainers() {
  auto config = MakeExclusivePcmConfig();
  Expect(aptt::IsWasapiExclusivePcmPlaybackFormat(config.format),
         "float32 PCM is accepted");
  Expect(aptt::IsWasapiExclusivePlaybackFormat(config.format),
         "float32 PCM is accepted by the combined gate");

  config.format = MakePcmFormat(aptt::SampleType::kInt16, 16, 16);
  Expect(aptt::IsWasapiExclusivePcmPlaybackFormat(config.format),
         "int16 PCM is accepted");
  Expect(aptt::IsWasapiExclusivePlaybackFormat(config.format),
         "int16 PCM is accepted by the combined gate");

  config.format = MakePcmFormat(aptt::SampleType::kInt24Packed, 24, 24);
  Expect(aptt::IsWasapiExclusivePcmPlaybackFormat(config.format),
         "packed 24-bit PCM is accepted when IsFormatSupported accepts it");

  config.format = MakePcmFormat(aptt::SampleType::kInt24In32, 24, 32);
  Expect(aptt::IsWasapiExclusivePcmPlaybackFormat(config.format),
         "24-in-32 PCM is accepted when IsFormatSupported accepts it");

  config.format = MakePcmFormat(aptt::SampleType::kInt32, 32, 32);
  Expect(aptt::IsWasapiExclusivePcmPlaybackFormat(config.format),
         "int32 PCM is accepted when IsFormatSupported accepts it");

  aptt::DopConfig dop;
  dop.dsd_rate_multiplier = 64;
  dop.channel_count = 2;
  config.format = aptt::MakeDopCarrierFormat(dop);
  Expect(!aptt::IsWasapiExclusivePcmPlaybackFormat(config.format),
         "DoP carrier is not accepted by the PCM-only gate");
  Expect(aptt::IsWasapiExclusiveDopCarrierFormat(config.format),
         "DoP carrier is accepted by the DoP carrier gate");
  Expect(aptt::IsWasapiExclusivePlaybackFormat(config.format),
         "DoP carrier is accepted by the combined gate");
}

void TestExclusivePcmByteConversionCoversIntegerContainers() {
  const std::vector<float> samples = {-1.0F, 0.0F, 1.0F, 0.5F};

  const auto int16 = aptt::ConvertFloat32InterleavedToWasapiPcmBytes(
      samples,
      2,
      MakePcmFormat(aptt::SampleType::kInt16, 16, 16));
  Expect(int16.size() == 8, "int16 conversion writes 2 bytes per sample");
  Expect(int16[0] == 0x00 && int16[1] == 0x80,
         "int16 conversion is little-endian signed PCM");

  const auto packed24 = aptt::ConvertFloat32InterleavedToWasapiPcmBytes(
      samples,
      2,
      MakePcmFormat(aptt::SampleType::kInt24Packed, 24, 24));
  Expect(packed24.size() == 12,
         "packed 24-bit conversion writes 3 bytes per sample");

  const auto int24_in_32 = aptt::ConvertFloat32InterleavedToWasapiPcmBytes(
      samples,
      2,
      MakePcmFormat(aptt::SampleType::kInt24In32, 24, 32));
  Expect(int24_in_32.size() == 16,
         "24-in-32 conversion writes 4 bytes per sample");
  Expect(int24_in_32[0] == 0x00,
         "24-in-32 conversion leaves the low byte silent/padded");

  const auto int32 = aptt::ConvertFloat32InterleavedToWasapiPcmBytes(
      samples,
      2,
      MakePcmFormat(aptt::SampleType::kInt32, 32, 32));
  Expect(int32.size() == 16, "int32 conversion writes 4 bytes per sample");

  const auto invalid = aptt::ConvertFloat32InterleavedToWasapiPcmBytes(
      {0.0F, 0.0F, 0.0F},
      2,
      MakePcmFormat(aptt::SampleType::kInt16, 16, 16));
  Expect(invalid.empty(), "misaligned interleaved input is rejected");
}

void TestExclusiveInitializeRequiresEndpointBeforeApiUse() {
  auto config = MakeExclusivePcmConfig();
  config.device.stable_id.clear();

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

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

void TestExclusiveResetIsDisabled() {
  aptt::WasapiExclusivePcmBackend backend;
  const auto result = backend.reset();

  Expect(!result.ok, "reset is disabled");
  Expect(result.error.message.find("disabled") != std::string::npos,
         "reset failure explains the drain/keep-warm lifecycle");
}

void TestDopCarrierMustMatchDsdRateBeforeApiUse() {
  auto config = MakeExclusivePcmConfig();
  aptt::DopConfig dop;
  dop.dsd_rate_multiplier = 64;
  dop.channel_count = 2;
  config.format = aptt::MakeDopCarrierFormat(dop);
  config.format.sample_rate_hz = 48000;

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

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

void TestWasapiExclusiveModeNotAllowedErrorIsActionable() {
  const int exclusive_not_allowed = static_cast<int>(0x8889000Eu);

  Expect(std::string_view(aptt::WasapiAudioClientErrorSymbol(
             exclusive_not_allowed)) ==
             "AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED",
         "exclusive-mode permission HRESULT is decoded");

  const auto message = aptt::DescribeWasapiAudioClientError(
      exclusive_not_allowed,
      "IAudioClient::Initialize",
      "failed to initialize WASAPI exclusive stream");
  Expect(message.find("exclusive mode is not allowed") != std::string::npos,
         "message explains exclusive-mode permission failure");
  Expect(message.find("Windows sound settings") != std::string::npos,
         "message gives an operator action");
}

}  // namespace

int main() {
  TestExclusivePolicyRequiresExactSupport();
  TestExclusivePolicySupportsTimerDrivenPeriodDefaults();
  TestExclusiveFormatGateAcceptsSupportedPcmContainers();
  TestExclusivePcmByteConversionCoversIntegerContainers();
  TestExclusiveInitializeRequiresEndpointBeforeApiUse();
  TestExclusiveResetIsDisabled();
  TestDopCarrierMustMatchDsdRateBeforeApiUse();
  TestWasapiExclusiveModeNotAllowedErrorIsActionable();

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