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

#include "backends/wasapi_format_probe.h"

namespace {

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

void TestDefaultCandidateIsConservativePcm() {
  const auto candidate = aptt::WasapiDefaultPcmCandidate();
  Expect(candidate.signal_mode == aptt::SignalMode::kPcm,
         "default candidate is PCM");
  Expect(candidate.sample_rate_hz == 48000, "default sample rate is 48 kHz");
  Expect(candidate.sample_type == aptt::SampleType::kFloat32,
         "default sample type is float32");
  Expect(candidate.channels.channel_count == 2,
         "default channel count is stereo");
  Expect(candidate.channels.channel_mask == 3,
         "default channel mask is stereo");
}

void TestPcmCandidatePreservesIntegerFormat() {
  const auto candidate =
      aptt::WasapiPcmCandidate(44100, aptt::SampleType::kInt16, 2);
  Expect(candidate.sample_rate_hz == 44100, "sample rate is preserved");
  Expect(candidate.sample_type == aptt::SampleType::kInt16,
         "sample type is preserved");
  Expect(candidate.valid_bits_per_sample == 16, "valid bits are 16");
  Expect(candidate.container_bits_per_sample == 16, "container bits are 16");
}

void TestDefaultPcmCandidatesCoverWideScanRange() {
  const auto candidates = aptt::WasapiDefaultPcmCandidates();
  Expect(candidates.size() == 65, "wide WASAPI PCM candidates");
  Expect(candidates.front().sample_rate_hz == 44100,
         "WASAPI PCM scan begins at 44.1 kHz");
  Expect(candidates.front().sample_type == aptt::SampleType::kInt16,
         "WASAPI PCM scan includes 16-bit integer");
  Expect(candidates[1].sample_type == aptt::SampleType::kInt24Packed,
         "WASAPI PCM scan distinguishes packed 24-bit");
  Expect(candidates[1].valid_bits_per_sample == 24 &&
             candidates[1].container_bits_per_sample == 24,
         "packed 24-bit is represented as 24/24");
  Expect(candidates[2].sample_type == aptt::SampleType::kInt24In32,
         "WASAPI PCM scan distinguishes 24-in-32");
  Expect(candidates[2].valid_bits_per_sample == 24 &&
             candidates[2].container_bits_per_sample == 32,
         "24-in-32 is represented as 24/32");
  Expect(candidates.back().sample_rate_hz == 1536000,
         "WASAPI PCM scan includes 1536 kHz");
  Expect(candidates.back().sample_type == aptt::SampleType::kInt32,
         "WASAPI PCM scan includes 32-bit integer");
}

void TestDopCarrierCandidateUsesExactPcmCarrier() {
  const auto candidate = aptt::WasapiDopCarrierCandidate(64, 2);

  Expect(candidate.signal_mode == aptt::SignalMode::kDop,
         "DoP carrier candidate is marked as DoP");
  Expect(candidate.sample_rate_hz == 176400,
         "DSD64 DoP carrier uses 176.4 kHz");
  Expect(candidate.sample_type == aptt::SampleType::kInt24In32,
         "DoP carrier uses 24 valid bits in a 32-bit PCM container");
  Expect(candidate.valid_bits_per_sample == 24, "DoP valid bits are 24");
  Expect(candidate.container_bits_per_sample == 32,
         "DoP container bits are 32");
  Expect(candidate.channels.channel_count == 2,
         "DoP carrier preserves channel count");
  Expect(candidate.dsd_rate_multiplier == 64,
         "DoP carrier records the DSD rate multiplier");
}

void TestDefaultDopCandidatesCoverWideDsdRange() {
  const auto candidates = aptt::WasapiDefaultDopCarrierCandidates(2);
  Expect(candidates.size() == 6, "wide WASAPI DoP DSD candidates");
  Expect(candidates.front().dsd_rate_multiplier == 64,
         "DoP scan includes DSD64");
  Expect(candidates.back().dsd_rate_multiplier == 2048,
         "DoP scan includes DSD2048");
  Expect(candidates.back().sample_rate_hz == 5644800,
         "DSD2048 DoP carrier is 5.6448 MHz");
}

void TestProbeRequiresExplicitEndpointIdBeforeAnyApiUse() {
  aptt::WasapiFormatProbeRequest request;
  request.candidate_formats.push_back(aptt::WasapiDefaultPcmCandidate());
  request.include_mix_format_candidate = false;

  const auto result = aptt::ProbeWasapiEndpointFormats(request);

  Expect(result.device.stable_id.empty(), "no implicit endpoint is selected");
  Expect(result.discovery_error.has_value(), "missing endpoint returns error");
  Expect(result.discovery_error->symbol == "E_INVALIDARG",
         "missing endpoint is rejected before probing");
  Expect(result.probes.empty(), "no probe records are created without endpoint");
}

void TestWasapiUnsupportedFormatResultIsNotAProbeError() {
  Expect(aptt::ClassifyWasapiFormatSupportResult(0, false) ==
             aptt::CapabilitySupport::kSupported,
         "S_OK is classified as supported");
  Expect(aptt::ClassifyWasapiFormatSupportResult(1, true) ==
             aptt::CapabilitySupport::kClosestMatch,
         "S_FALSE with a closest match is classified as closest match");
  Expect(aptt::ClassifyWasapiFormatSupportResult(
             static_cast<std::int32_t>(0x88890008u),
             false) == aptt::CapabilitySupport::kUnsupported,
         "AUDCLNT_E_UNSUPPORTED_FORMAT is classified as unsupported");
  Expect(aptt::ClassifyWasapiFormatSupportResult(
             static_cast<std::int32_t>(0x8889000Au),
             false) == aptt::CapabilitySupport::kFailed,
         "unexpected WASAPI failures remain probe errors");
}

}  // namespace

int main() {
  TestDefaultCandidateIsConservativePcm();
  TestPcmCandidatePreservesIntegerFormat();
  TestDefaultPcmCandidatesCoverWideScanRange();
  TestDopCarrierCandidateUsesExactPcmCarrier();
  TestDefaultDopCandidatesCoverWideDsdRange();
  TestProbeRequiresExplicitEndpointIdBeforeAnyApiUse();
  TestWasapiUnsupportedFormatResultIsNotAProbeError();

  std::cout << "WASAPI format probe tests passed\n";
  return 0;
}
