#include "backends/asio_pcm_backend.h"

#include <algorithm>
#include <array>
#include <atomic>
#include <chrono>
#include <cmath>
#include <cstring>
#include <limits>
#include <mutex>
#include <optional>
#include <sstream>
#include <thread>
#include <utility>

#include "backends/asio_driver_discovery.h"
#include "core/dop_generator.h"
#include "core/high_load_diagnostics.h"
#include "core/signal_generator.h"

#ifndef APTT_ENABLE_ASIO
#define APTT_ENABLE_ASIO 0
#endif

#if APTT_ENABLE_ASIO && defined(_WIN32)
#include "asiosys.h"
#include "asio.h"
#include "asiodrivers.h"

extern bool loadAsioDriver(char* name);
#endif

namespace aptt {
namespace {

constexpr int kAsioInvalidArgument = 0xA52000;
constexpr int kAsioDisabled = 0xA52001;
constexpr int kAsioInvalidState = 0xA52002;
constexpr int kAsioResetDisabled = 0xA52003;
constexpr int kAsioDriverLoadFailed = 0xA52005;
constexpr int kAsioDriverInitFailed = 0xA52006;
constexpr int kAsioDriverQueryFailed = 0xA52007;
constexpr int kAsioSampleRateFailed = 0xA52008;
constexpr int kAsioBufferCreateFailed = 0xA52009;
constexpr int kAsioUnsupportedSampleType = 0xA5200A;
constexpr int kAsioStartFailed = 0xA5200B;
constexpr int kAsioStopFailed = 0xA5200C;
constexpr int kAsioDisposeFailed = 0xA5200D;
constexpr int kAsioExitFailed = 0xA5200E;
constexpr int kAsioNotImplemented =
    static_cast<int>(static_cast<std::int32_t>(0x80004001u));

std::int32_t ClampPcm32(double value) {
  const double clamped = std::max(-1.0, std::min(1.0, value));
  return static_cast<std::int32_t>(std::lrint(clamped * 2147483647.0));
}

std::uint64_t DurationFrames(const PlaybackConfig& config) {
  if (config.continuous) {
    return std::numeric_limits<std::uint64_t>::max();
  }
  return std::max<std::uint64_t>(
      1,
      (static_cast<std::uint64_t>(config.format.sample_rate_hz) *
       config.duration_ms) /
          1000);
}

std::string FormatSummary(const FormatDescriptor& format) {
  std::ostringstream summary;
  summary << format.sample_rate_hz << " Hz "
          << format.channels.channel_count << " ch "
          << ToString(format.sample_type) << " valid_bits="
          << format.valid_bits_per_sample << " container_bits="
          << format.container_bits_per_sample;
  return summary.str();
}

bool IsDopMode(const FormatDescriptor& format) {
  return format.signal_mode == SignalMode::kDop;
}

bool SameFormat(const FormatDescriptor& left, const FormatDescriptor& right) {
  return left.signal_mode == right.signal_mode &&
         left.sample_rate_hz == right.sample_rate_hz &&
         left.sample_type == right.sample_type &&
         left.valid_bits_per_sample == right.valid_bits_per_sample &&
         left.container_bits_per_sample == right.container_bits_per_sample &&
         left.channels.channel_count == right.channels.channel_count &&
         left.channels.channel_mask == right.channels.channel_mask &&
         left.dsd_rate_multiplier == right.dsd_rate_multiplier;
}

void PushUniqueFormat(std::vector<FormatDescriptor>& formats,
                      const FormatDescriptor& candidate) {
  const auto found = std::find_if(
      formats.begin(),
      formats.end(),
      [&](const FormatDescriptor& existing) {
        return SameFormat(existing, candidate);
      });
  if (found == formats.end()) {
    formats.push_back(candidate);
  }
}

DopConfig DopConfigFromFormat(const FormatDescriptor& format) {
  DopConfig config;
  config.dsd_rate_multiplier = format.dsd_rate_multiplier.value_or(0);
  config.channel_count = format.channels.channel_count;
  config.dsd_byte_order = SampleType::kDsd1BitLsbFirst;
  config.marker_starts_with_0x05 = format.dop_marker_starts_with_0x05;
  return config;
}

const char* KeepAliveFormatName(const FormatDescriptor& format) {
  return IsDopMode(format) ? "valid-dop-silence" : "valid-pcm-silence";
}

bool IsAsioCarrierPlaybackFormat(const FormatDescriptor& format) {
  return IsAsioPcmPlaybackFormat(format) || IsAsioDopCarrierFormat(format);
}

std::optional<AsioPcmSampleType> AsioSampleTypeForFormat(
    const FormatDescriptor& format) {
  if (!IsAsioCarrierPlaybackFormat(format)) {
    return std::nullopt;
  }
  if (IsDopMode(format)) {
    return AsioPcmSampleType::kInt24In32Lsb;
  }
  switch (format.sample_type) {
    case SampleType::kInt16:
      return AsioPcmSampleType::kInt16Lsb;
    case SampleType::kInt24Packed:
      return AsioPcmSampleType::kInt24Lsb;
    case SampleType::kInt24In32:
      return AsioPcmSampleType::kInt24In32Lsb;
    case SampleType::kInt32:
      return AsioPcmSampleType::kInt32Lsb;
    case SampleType::kFloat32:
      return AsioPcmSampleType::kFloat32Lsb;
    case SampleType::kFloat64:
      return AsioPcmSampleType::kFloat64Lsb;
    case SampleType::kDsd1BitLsbFirst:
    case SampleType::kDsd1BitMsbFirst:
    case SampleType::kDsd8Bit:
      return std::nullopt;
  }
  return std::nullopt;
}

const char* ToString(AsioPcmSampleType sample_type) {
  switch (sample_type) {
    case AsioPcmSampleType::kInt16Lsb:
      return "ASIOSTInt16LSB";
    case AsioPcmSampleType::kInt24Lsb:
      return "ASIOSTInt24LSB";
    case AsioPcmSampleType::kInt24In32Lsb:
      return "ASIOSTInt32LSB24";
    case AsioPcmSampleType::kInt32Lsb:
      return "ASIOSTInt32LSB";
    case AsioPcmSampleType::kFloat32Lsb:
      return "ASIOSTFloat32LSB";
    case AsioPcmSampleType::kFloat64Lsb:
      return "ASIOSTFloat64LSB";
  }
  return "unknown";
}

OperationResult ValidateConfigForAsioPcm(const PlaybackConfig& config) {
  if (config.backend != BackendApi::kAsio) {
    return OperationResult::Failure(
        kAsioInvalidArgument,
        "ASIO PCM/DoP carrier playback requires BackendApi::kAsio");
  }
  if (config.device.stable_id.empty() ||
      config.device.stable_id == "asio:disabled") {
    return OperationResult::Failure(
        kAsioInvalidArgument,
        "ASIO PCM/DoP carrier playback requires an explicit ASIO driver ID");
  }
  if (!IsAsioCarrierPlaybackFormat(config.format)) {
    return OperationResult::Failure(
        kAsioInvalidArgument,
        "ASIO playback requires a supported PCM format or explicit DoP carrier");
  }
  if (IsDopMode(config.format)) {
    if (!std::isfinite(config.frequency_hz) || config.frequency_hz <= 0.0) {
      return OperationResult::Failure(
          kAsioInvalidArgument,
          "ASIO DoP carrier playback requires a positive signal frequency");
    }
    if (!std::isfinite(config.amplitude_dbfs) || config.amplitude_dbfs > 0.0) {
      return OperationResult::Failure(
          kAsioInvalidArgument,
          "ASIO DoP carrier playback requires amplitude <= 0 dBFS");
    }
  }
  if (config.format.sample_rate_hz == 0 ||
      config.format.channels.channel_count == 0) {
    return OperationResult::Failure(
        kAsioInvalidArgument,
        "ASIO PCM/DoP carrier playback requires a non-zero sample rate and channel count");
  }
  return OperationResult::Success();
}

void AppendInt16(std::vector<std::uint8_t>& output, std::int32_t value) {
  const auto sample = static_cast<std::int16_t>(value >> 16);
  output.push_back(static_cast<std::uint8_t>(sample & 0xFF));
  output.push_back(static_cast<std::uint8_t>((sample >> 8) & 0xFF));
}

void AppendInt24(std::vector<std::uint8_t>& output, std::int32_t value) {
  const std::int32_t sample = value >> 8;
  output.push_back(static_cast<std::uint8_t>(sample & 0xFF));
  output.push_back(static_cast<std::uint8_t>((sample >> 8) & 0xFF));
  output.push_back(static_cast<std::uint8_t>((sample >> 16) & 0xFF));
}

void AppendUint32(std::vector<std::uint8_t>& output, std::uint32_t value) {
  output.push_back(static_cast<std::uint8_t>(value & 0xFF));
  output.push_back(static_cast<std::uint8_t>((value >> 8) & 0xFF));
  output.push_back(static_cast<std::uint8_t>((value >> 16) & 0xFF));
  output.push_back(static_cast<std::uint8_t>((value >> 24) & 0xFF));
}

void AppendInt32(std::vector<std::uint8_t>& output, std::int32_t value) {
  AppendUint32(output, static_cast<std::uint32_t>(value));
}

void AppendInt24In32(std::vector<std::uint8_t>& output, std::int32_t value) {
  AppendUint32(output, static_cast<std::uint32_t>(value) & 0xFFFFFF00u);
}

void AppendFloat32(std::vector<std::uint8_t>& output, float value) {
  const std::size_t offset = output.size();
  output.resize(offset + sizeof(float));
  std::memcpy(output.data() + offset, &value, sizeof(float));
}

void AppendFloat64(std::vector<std::uint8_t>& output, double value) {
  const std::size_t offset = output.size();
  output.resize(offset + sizeof(double));
  std::memcpy(output.data() + offset, &value, sizeof(double));
}

#if APTT_ENABLE_ASIO && defined(_WIN32)

class AsioCallbackSink {
 public:
  virtual ~AsioCallbackSink() = default;
  virtual void OnAsioBufferSwitch(long buffer_index,
                                  bool direct_process,
                                  bool has_time_info) = 0;
  virtual void OnAsioSampleRateChanged(double sample_rate) = 0;
  virtual long OnAsioMessage(long selector, long value) = 0;
};

std::mutex g_asio_callback_mutex;
AsioCallbackSink* g_asio_callback_sink = nullptr;

AsioCallbackSink* ActiveAsioCallbackSink() {
  std::lock_guard lock(g_asio_callback_mutex);
  return g_asio_callback_sink;
}

void SetActiveAsioCallbackSink(AsioCallbackSink* sink) {
  std::lock_guard lock(g_asio_callback_mutex);
  g_asio_callback_sink = sink;
}

void AsioBufferSwitch(long buffer_index, ASIOBool direct_process) {
  if (auto* sink = ActiveAsioCallbackSink()) {
    sink->OnAsioBufferSwitch(buffer_index, direct_process == ASIOTrue, false);
  }
}

ASIOTime* AsioBufferSwitchTimeInfo(ASIOTime* params,
                                   long buffer_index,
                                   ASIOBool direct_process) {
  if (auto* sink = ActiveAsioCallbackSink()) {
    sink->OnAsioBufferSwitch(buffer_index, direct_process == ASIOTrue, true);
  }
  return params;
}

void AsioSampleRateChanged(ASIOSampleRate sample_rate) {
  if (auto* sink = ActiveAsioCallbackSink()) {
    sink->OnAsioSampleRateChanged(static_cast<double>(sample_rate));
  }
}

long AsioMessages(long selector, long value, void*, double*) {
  if (auto* sink = ActiveAsioCallbackSink()) {
    return sink->OnAsioMessage(selector, value);
  }
  return 0;
}

std::optional<AsioPcmSampleType> AsioSampleTypeFromSdk(
    ASIOSampleType sample_type) {
  switch (sample_type) {
    case ASIOSTInt16LSB:
      return AsioPcmSampleType::kInt16Lsb;
    case ASIOSTInt24LSB:
      return AsioPcmSampleType::kInt24Lsb;
    case ASIOSTInt32LSB24:
      return AsioPcmSampleType::kInt24In32Lsb;
    case ASIOSTInt32LSB:
      return AsioPcmSampleType::kInt32Lsb;
    case ASIOSTFloat32LSB:
      return AsioPcmSampleType::kFloat32Lsb;
    case ASIOSTFloat64LSB:
      return AsioPcmSampleType::kFloat64Lsb;
    default:
      return std::nullopt;
  }
}

const char* AsioErrorSymbol(ASIOError error) {
  switch (error) {
    case ASE_OK:
      return "ASE_OK";
    case ASE_NotPresent:
      return "ASE_NotPresent";
    case ASE_HWMalfunction:
      return "ASE_HWMalfunction";
    case ASE_InvalidParameter:
      return "ASE_InvalidParameter";
    case ASE_InvalidMode:
      return "ASE_InvalidMode";
    case ASE_SPNotAdvancing:
      return "ASE_SPNotAdvancing";
    case ASE_NoClock:
      return "ASE_NoClock";
    case ASE_NoMemory:
      return "ASE_NoMemory";
    default:
      return "ASE_Unknown";
  }
}

bool TryLoadAsioDriverName(const std::string& name) {
  if (name.empty()) {
    return false;
  }
  std::array<char, 128> driver_name{};
  const std::size_t bytes =
      std::min<std::size_t>(name.size(), driver_name.size() - 1);
  std::memcpy(driver_name.data(), name.data(), bytes);
  return loadAsioDriver(driver_name.data());
}

void CoolDownBeforeExplicitProbeExit() {
  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}

#endif

}  // namespace

AsioPcmPolicy MakeAsioPcmPolicy(const PlaybackConfig& config) {
  AsioPcmPolicy policy;
  policy.keep_warm_after_signal =
      config.hold_mode == HoldMode::kKeepWarmAfterStop;
  policy.release_after_drain =
      config.hold_mode == HoldMode::kReleaseAfterDrain;
  policy.uses_output_ready_if_supported =
      config.asio_use_output_ready_if_supported;
  policy.release_cooldown_ms = config.release_cooldown_ms == 0
                                   ? 1
                                   : config.release_cooldown_ms;
  return policy;
}

bool IsAsioPcmPlaybackFormat(const FormatDescriptor& format) {
  if (format.signal_mode != SignalMode::kPcm) {
    return false;
  }
  switch (format.sample_type) {
    case SampleType::kInt16:
      return format.valid_bits_per_sample == 16 &&
             format.container_bits_per_sample == 16;
    case SampleType::kInt24Packed:
      return format.valid_bits_per_sample == 24 &&
             format.container_bits_per_sample == 24;
    case SampleType::kInt24In32:
      return format.valid_bits_per_sample == 24 &&
             format.container_bits_per_sample == 32;
    case SampleType::kInt32:
      return format.valid_bits_per_sample == 32 &&
             format.container_bits_per_sample == 32;
    case SampleType::kFloat32:
      return format.valid_bits_per_sample == 32 &&
             format.container_bits_per_sample == 32;
    case SampleType::kFloat64:
      return format.valid_bits_per_sample == 64 &&
             format.container_bits_per_sample == 64;
    case SampleType::kDsd1BitLsbFirst:
    case SampleType::kDsd1BitMsbFirst:
    case SampleType::kDsd8Bit:
      return false;
  }
  return false;
}

bool IsAsioDopCarrierFormat(const FormatDescriptor& format) {
  if (format.signal_mode != SignalMode::kDop) {
    return false;
  }
  if (format.sample_type != SampleType::kInt24In32 ||
      format.valid_bits_per_sample != 24 ||
      format.container_bits_per_sample != 32) {
    return false;
  }
  if (!format.dsd_rate_multiplier ||
      !IsSupportedDopRate(*format.dsd_rate_multiplier)) {
    return false;
  }
  if (format.sample_rate_hz !=
      DopCarrierSampleRateHz(*format.dsd_rate_multiplier)) {
    return false;
  }
  return format.channels.channel_count > 0;
}

std::uint32_t AsioBytesPerSample(AsioPcmSampleType sample_type) {
  switch (sample_type) {
    case AsioPcmSampleType::kInt16Lsb:
      return 2;
    case AsioPcmSampleType::kInt24Lsb:
      return 3;
    case AsioPcmSampleType::kInt24In32Lsb:
    case AsioPcmSampleType::kInt32Lsb:
    case AsioPcmSampleType::kFloat32Lsb:
      return 4;
    case AsioPcmSampleType::kFloat64Lsb:
      return 8;
  }
  return 0;
}

std::vector<std::vector<std::uint8_t>> ConvertFloat32InterleavedToAsioPlanar(
    const std::vector<float>& interleaved_samples,
    std::uint32_t channel_count,
    AsioPcmSampleType sample_type) {
  if (channel_count == 0 ||
      (interleaved_samples.size() % channel_count) != 0) {
    return {};
  }

  const std::size_t frame_count =
      interleaved_samples.size() / channel_count;
  const std::uint32_t bytes_per_sample = AsioBytesPerSample(sample_type);
  std::vector<std::vector<std::uint8_t>> planar(channel_count);
  for (auto& channel : planar) {
    channel.reserve(frame_count * bytes_per_sample);
  }

  for (std::size_t frame = 0; frame < frame_count; ++frame) {
    for (std::uint32_t channel = 0; channel < channel_count; ++channel) {
      const float sample =
          interleaved_samples[frame * channel_count + channel];
      auto& output = planar[channel];
      const std::int32_t pcm32 = ClampPcm32(sample);
      switch (sample_type) {
        case AsioPcmSampleType::kInt16Lsb:
          AppendInt16(output, pcm32);
          break;
        case AsioPcmSampleType::kInt24Lsb:
          AppendInt24(output, pcm32);
          break;
        case AsioPcmSampleType::kInt24In32Lsb:
          AppendInt24In32(output, pcm32);
          break;
        case AsioPcmSampleType::kInt32Lsb:
          AppendInt32(output, pcm32);
          break;
        case AsioPcmSampleType::kFloat32Lsb:
          AppendFloat32(output, sample);
          break;
        case AsioPcmSampleType::kFloat64Lsb:
          AppendFloat64(output, static_cast<double>(sample));
          break;
      }
    }
  }
  return planar;
}

std::vector<std::vector<std::uint8_t>> ConvertInterleavedDop24In32ToAsioPlanar(
    const std::vector<std::uint8_t>& interleaved_dop_bytes,
    std::uint32_t channel_count) {
  constexpr std::uint32_t kBytesPerDopCarrierSample = 4;
  if (channel_count == 0 ||
      (interleaved_dop_bytes.size() %
       (static_cast<std::size_t>(channel_count) *
        kBytesPerDopCarrierSample)) != 0) {
    return {};
  }

  const std::size_t frame_count =
      interleaved_dop_bytes.size() /
      (static_cast<std::size_t>(channel_count) * kBytesPerDopCarrierSample);
  std::vector<std::vector<std::uint8_t>> planar(channel_count);
  for (auto& channel : planar) {
    channel.resize(frame_count * kBytesPerDopCarrierSample);
  }

  for (std::size_t frame = 0; frame < frame_count; ++frame) {
    for (std::uint32_t channel = 0; channel < channel_count; ++channel) {
      const std::size_t source =
          (frame * channel_count + channel) * kBytesPerDopCarrierSample;
      const std::size_t destination =
          frame * kBytesPerDopCarrierSample;
      std::memcpy(
          planar[channel].data() + destination,
          interleaved_dop_bytes.data() + source,
          kBytesPerDopCarrierSample);
    }
  }
  return planar;
}

DiagnosticEvent MakeAsioPcmPreparedEvent(
    std::uint64_t sequence,
    std::string device_id,
    const FormatDescriptor& format,
    const AsioBufferConstraints& constraints) {
  DiagnosticEvent event;
  event.type = DiagnosticEventType::kFormatProbe;
  event.sequence = sequence;
  event.backend = BackendApi::kAsio;
  event.device_id = std::move(device_id);
  event.format = format;
  event.message = IsDopMode(format)
      ? "ASIO DoP carrier stream prepared"
      : "ASIO PCM stream prepared";
  event.backend_fields["requested_format"] = FormatSummary(format);
  event.backend_fields["accepted_format"] = FormatSummary(format);
  event.backend_fields["signal_mode"] = ToString(format.signal_mode);
  event.backend_fields["sample_type"] = ToString(format.sample_type);
  event.backend_fields["buffer_min"] = std::to_string(constraints.min_size);
  event.backend_fields["buffer_max"] = std::to_string(constraints.max_size);
  event.backend_fields["buffer_preferred"] =
      std::to_string(constraints.preferred_size);
  event.backend_fields["buffer_granularity"] =
      std::to_string(constraints.granularity);
  event.backend_fields["buffer_frames"] =
      std::to_string(constraints.preferred_size);
  event.backend_fields["input_latency"] =
      std::to_string(constraints.input_latency);
  event.backend_fields["output_latency"] =
      std::to_string(constraints.output_latency);
  event.backend_fields["output_ready_supported"] =
      constraints.output_ready_supported ? "true" : "false";
  event.backend_fields["keep_alive_format"] = KeepAliveFormatName(format);
  event.backend_fields["callback_mode"] = "ASIO bufferSwitch";
  event.backend_fields["opens_control_panel"] = "false";
  event.backend_fields["repeated_asio_exit"] = "false";
  if (IsDopMode(format)) {
    const auto dop_config = DopConfigFromFormat(format);
    event.backend_fields["dop_dsd_rate_multiplier"] =
        std::to_string(dop_config.dsd_rate_multiplier);
    event.backend_fields["dop_marker_first"] =
        dop_config.marker_starts_with_0x05 ? "0x05" : "0xFA";
    event.backend_fields["dop_dsd_byte_order"] =
        ToString(dop_config.dsd_byte_order);
    event.backend_fields["pcm_carrier_sample_type"] =
        ToString(format.sample_type);
  }
  return event;
}

DiagnosticEvent MakeAsioPcmRuntimeEvent(
    std::uint64_t sequence,
    std::string device_id,
    const RealtimeStats& stats,
    std::int32_t buffer_index,
    std::int32_t buffer_frames,
    double callback_duration_ms,
    bool direct_process,
    bool output_ready_called) {
  DiagnosticEvent event;
  event.type = DiagnosticEventType::kRuntimeStats;
  event.sequence = sequence;
  event.backend = BackendApi::kAsio;
  event.device_id = std::move(device_id);
  event.message = "ASIO buffer switch";
  event.realtime_stats = stats;
  event.backend_fields["buffer_index"] = std::to_string(buffer_index);
  event.backend_fields["buffer_frames"] = std::to_string(buffer_frames);
  event.backend_fields["submitted_frames"] = std::to_string(buffer_frames);
  event.backend_fields["callback_duration_ms"] =
      std::to_string(callback_duration_ms);
  event.backend_fields["direct_process"] = direct_process ? "true" : "false";
  event.backend_fields["output_ready_called"] =
      output_ready_called ? "true" : "false";
  event.backend_fields["keep_alive_format"] = "valid-pcm-silence";
  return event;
}

struct AsioPcmBackend::Impl
#if APTT_ENABLE_ASIO && defined(_WIN32)
    : public AsioCallbackSink
#endif
{
  ~Impl() { Shutdown(); }

  BackendApi Api() const { return BackendApi::kAsio; }

  DeviceList EnumerateDevices() {
    DeviceList devices;
    const auto snapshot = EnumerateAsioDrivers();
    devices.reserve(snapshot.devices.size());
    for (const auto& device_snapshot : snapshot.devices) {
      devices.push_back(device_snapshot.device);
    }
    return devices;
  }

  FormatProbeResult ProbeFormats(const DeviceInfo& device) {
    FormatProbeResult result;
    result.requested.signal_mode = SignalMode::kPcm;
    result.requested.sample_rate_hz = 48000;
    result.requested.sample_type = SampleType::kFloat32;
    result.requested.valid_bits_per_sample = 32;
    result.requested.container_bits_per_sample = 32;
    result.requested.channels.channel_count = 2;
    result.requested.channels.channel_mask = 3;

    if (device.stable_id.empty() || device.stable_id == "asio:disabled") {
      result.rejection_reasons.push_back(
          "ASIO PCM format probe requires an explicit ASIO driver ID");
      return result;
    }
    if (!IsAsioSdkEnabled()) {
      result.rejection_reasons.push_back(
          "ASIO SDK integration is disabled at build time");
      return result;
    }

#if !(APTT_ENABLE_ASIO && defined(_WIN32))
    result.rejection_reasons.push_back(
        "ASIO PCM format probe is available only on Windows with ENABLE_ASIO");
    return result;
#else
    if (!TryLoadAsioDriverName(device.display_name) &&
        !TryLoadAsioDriverName(device.driver_name)) {
      result.rejection_reasons.push_back("ASIO driver could not be loaded");
      return result;
    }

    ASIODriverInfo driver_info{};
    driver_info.asioVersion = 2;
    ASIOError asio_result = ASIOInit(&driver_info);
    if (asio_result != ASE_OK) {
      result.rejection_reasons.push_back("ASIOInit failed during PCM probe");
      CoolDownBeforeExplicitProbeExit();
      ASIOExit();
      return result;
    }

    long input_channels = 0;
    long output_channels = 0;
    asio_result = ASIOGetChannels(&input_channels, &output_channels);
    if (asio_result != ASE_OK || output_channels <= 0) {
      result.rejection_reasons.push_back(
          "ASIO driver reports no output channels");
      CoolDownBeforeExplicitProbeExit();
      ASIOExit();
      return result;
    }

    ASIOSampleRate current_rate = 0.0;
    if (ASIOGetSampleRate(&current_rate) == ASE_OK && current_rate > 0.0) {
      result.requested.sample_rate_hz =
          static_cast<std::uint32_t>(std::llround(current_rate));
    }

    ASIOChannelInfo channel_info{};
    channel_info.channel = 0;
    channel_info.isInput = ASIOFalse;
    asio_result = ASIOGetChannelInfo(&channel_info);
    if (asio_result == ASE_OK) {
      if (const auto sample_type = AsioSampleTypeFromSdk(channel_info.type)) {
        switch (*sample_type) {
          case AsioPcmSampleType::kInt16Lsb:
            result.requested.sample_type = SampleType::kInt16;
            result.requested.valid_bits_per_sample = 16;
            result.requested.container_bits_per_sample = 16;
            break;
          case AsioPcmSampleType::kInt24Lsb:
            result.requested.sample_type = SampleType::kInt24Packed;
            result.requested.valid_bits_per_sample = 24;
            result.requested.container_bits_per_sample = 24;
            break;
          case AsioPcmSampleType::kInt24In32Lsb:
            result.requested.sample_type = SampleType::kInt24In32;
            result.requested.valid_bits_per_sample = 24;
            result.requested.container_bits_per_sample = 32;
            break;
          case AsioPcmSampleType::kInt32Lsb:
            result.requested.sample_type = SampleType::kInt32;
            result.requested.valid_bits_per_sample = 32;
            result.requested.container_bits_per_sample = 32;
            break;
          case AsioPcmSampleType::kFloat32Lsb:
            result.requested.sample_type = SampleType::kFloat32;
            result.requested.valid_bits_per_sample = 32;
            result.requested.container_bits_per_sample = 32;
            break;
          case AsioPcmSampleType::kFloat64Lsb:
            result.requested.sample_type = SampleType::kFloat64;
            result.requested.valid_bits_per_sample = 64;
            result.requested.container_bits_per_sample = 64;
            break;
        }
        result.requested.channels.channel_count =
            static_cast<std::uint32_t>(std::min<long>(2, output_channels));
        result.requested.channels.channel_mask =
            result.requested.channels.channel_count == 1 ? 1u : 3u;

        constexpr std::uint32_t kProbeSampleRatesHz[] = {
            44100, 48000, 88200, 96000, 176400, 192000, 352800,
            384000, 705600, 768000, 786000, 1411200, 1536000};
        if (result.requested.sample_rate_hz > 0 &&
            ASIOCanSampleRate(static_cast<ASIOSampleRate>(
                result.requested.sample_rate_hz)) == ASE_OK) {
          PushUniqueFormat(result.supported_formats, result.requested);
        }
        for (const auto sample_rate_hz : kProbeSampleRatesHz) {
          if (ASIOCanSampleRate(
                  static_cast<ASIOSampleRate>(sample_rate_hz)) != ASE_OK) {
            continue;
          }
          auto candidate = result.requested;
          candidate.sample_rate_hz = sample_rate_hz;
          PushUniqueFormat(result.supported_formats, candidate);
        }
        if (result.supported_formats.empty()) {
          result.rejection_reasons.push_back(
              "ASIO driver sample type is supported, but none of the requested PCM rates was accepted");
        }
      } else {
        result.rejection_reasons.push_back(
            "ASIO driver output sample type is not supported by this PCM slice");
      }
    } else {
      result.rejection_reasons.push_back(
          "ASIOGetChannelInfo failed during PCM probe");
    }

    CoolDownBeforeExplicitProbeExit();
    ASIOExit();
    return result;
#endif
  }

  FormatProbeResult ProbeDopFormats(const DeviceInfo& device,
                                    const DopConfig& requested_dop) {
    FormatProbeResult result;
    result.requested = MakeDopCarrierFormat(requested_dop);

    if (device.stable_id.empty() || device.stable_id == "asio:disabled") {
      result.rejection_reasons.push_back(
          "ASIO DoP carrier probe requires an explicit ASIO driver ID");
      return result;
    }
    if (!IsAsioSdkEnabled()) {
      result.rejection_reasons.push_back(
          "ASIO SDK integration is disabled at build time");
      return result;
    }

#if !(APTT_ENABLE_ASIO && defined(_WIN32))
    result.rejection_reasons.push_back(
        "ASIO DoP carrier probe is available only on Windows with ENABLE_ASIO");
    return result;
#else
    if (!TryLoadAsioDriverName(device.display_name) &&
        !TryLoadAsioDriverName(device.driver_name)) {
      result.rejection_reasons.push_back("ASIO driver could not be loaded");
      return result;
    }

    ASIODriverInfo driver_info{};
    driver_info.asioVersion = 2;
    ASIOError asio_result = ASIOInit(&driver_info);
    if (asio_result != ASE_OK) {
      result.rejection_reasons.push_back(
          "ASIOInit failed during DoP carrier probe");
      CoolDownBeforeExplicitProbeExit();
      ASIOExit();
      return result;
    }

    long input_channels = 0;
    long output_channels = 0;
    asio_result = ASIOGetChannels(&input_channels, &output_channels);
    if (asio_result != ASE_OK ||
        output_channels < static_cast<long>(requested_dop.channel_count)) {
      std::ostringstream reason;
      reason << "ASIO driver does not expose enough output channels for "
             << requested_dop.channel_count << " channel DoP";
      result.rejection_reasons.push_back(reason.str());
      CoolDownBeforeExplicitProbeExit();
      ASIOExit();
      return result;
    }

    ASIOChannelInfo channel_info{};
    channel_info.channel = 0;
    channel_info.isInput = ASIOFalse;
    asio_result = ASIOGetChannelInfo(&channel_info);
    const auto sample_type = asio_result == ASE_OK
        ? AsioSampleTypeFromSdk(channel_info.type)
        : std::optional<AsioPcmSampleType>{};
    if (!sample_type ||
        *sample_type != AsioPcmSampleType::kInt24In32Lsb) {
      result.rejection_reasons.push_back(
          "ASIO driver does not expose ASIOSTInt32LSB24 required for DoP carrier");
      CoolDownBeforeExplicitProbeExit();
      ASIOExit();
      return result;
    }

    std::vector<FormatDescriptor> candidates;
    PushUniqueFormat(candidates, MakeDopCarrierFormat(requested_dop));
    for (const std::uint32_t multiplier :
         {64u, 128u, 256u, 512u, 1024u, 2048u}) {
      DopConfig dop;
      dop.dsd_rate_multiplier = multiplier;
      dop.channel_count = requested_dop.channel_count;
      PushUniqueFormat(candidates, MakeDopCarrierFormat(dop));
    }
    for (const auto& candidate : candidates) {
      const ASIOSampleRate carrier_rate =
          static_cast<ASIOSampleRate>(candidate.sample_rate_hz);
      const ASIOError can_rate = ASIOCanSampleRate(carrier_rate);
      if (can_rate == ASE_OK && IsAsioDopCarrierFormat(candidate)) {
        result.supported_formats.push_back(candidate);
      } else {
        std::ostringstream reason;
        const auto multiplier =
            candidate.dsd_rate_multiplier.value_or(requested_dop.dsd_rate_multiplier);
        reason << "ASIO driver rejected DoP DSD" << multiplier
               << " carrier rate " << candidate.sample_rate_hz << " Hz";
        result.rejection_reasons.push_back(reason.str());
      }
    }
    if (result.supported_formats.empty() &&
        result.rejection_reasons.empty()) {
      result.rejection_reasons.push_back(
          "ASIO driver did not expose an exact DoP carrier format");
    }

    CoolDownBeforeExplicitProbeExit();
    ASIOExit();
    return result;
#endif
  }

  OperationResult Initialize(const PlaybackConfig& config) {
    auto validation = ValidateConfigForAsioPcm(config);
    if (!validation.ok) {
      SetLastError(validation.error);
      return validation;
    }
    if (!IsAsioSdkEnabled()) {
      return Fail(
          kAsioDisabled,
          "ASIO PCM/DoP carrier playback is disabled because ENABLE_ASIO is OFF");
    }

    Shutdown();

    {
      std::scoped_lock lock(state_mutex_, stats_mutex_, events_mutex_);
      config_ = config;
      policy_ = MakeAsioPcmPolicy(config_);
      stats_ = {};
      events_.clear();
      sequence_ = 0;
      lifecycle_state_ = DeviceLifecycleState::kDiscovered;
      constraints_ = {};
      asio_sample_type_.reset();
      output_channels_ = 0;
      current_sample_rate_hz_ = 0.0;
      sample_rate_set_result_ = "not-queried";
      signal_frame_target_ = DurationFrames(config_);
      signal_frames_written_ = 0;
      force_silence_ = false;
      last_error_ = {};
      generator_.ResetPhase();
      dop_generator_.Reset();
    }

    if (!TransitionTo(DeviceLifecycleState::kReserved,
                      "selected ASIO driver reserved")) {
      return OperationResult::Failure(kAsioInvalidState, GetLastError().message);
    }

#if !(APTT_ENABLE_ASIO && defined(_WIN32))
    TransitionTo(DeviceLifecycleState::kFaulted,
                 "ASIO PCM/DoP carrier playback is not available");
    return Fail(
        kAsioNotImplemented,
        "ASIO PCM/DoP carrier playback is available only on Windows with ENABLE_ASIO");
#else
    return InitializeAsioDriver();
#endif
  }

  OperationResult Start() {
#if !(APTT_ENABLE_ASIO && defined(_WIN32))
    return Fail(
        kAsioDisabled,
        "ASIO PCM/DoP carrier playback is disabled because ENABLE_ASIO is OFF");
#else
    const auto current = GetState();
    if (current == DeviceLifecycleState::kRunningSilence) {
      return Fail(
          kAsioInvalidState,
          "ASIO RunningSilence restart requires explicit release before rerun");
    }
    if (current != DeviceLifecycleState::kPrepared &&
        current != DeviceLifecycleState::kHeldOpen) {
      return Fail(kAsioInvalidState, "ASIO PCM stream is not prepared");
    }
    if (!buffers_created_ || buffer_infos_.empty()) {
      return Fail(kAsioInvalidState, "ASIO PCM buffers are not prepared");
    }

    force_silence_ = false;
    signal_frames_written_ = 0;
    generator_.ResetPhase();
    dop_generator_.Reset();
    last_callback_time_ = std::chrono::steady_clock::now();
    FillOutputBuffer(0, false, false, false);
    FillOutputBuffer(1, false, false, false);

    if (!TransitionTo(DeviceLifecycleState::kRunningSignal,
                      IsDopMode(config_.format)
                          ? "ASIO 1 kHz DoP carrier signal started"
                          : "ASIO 1 kHz PCM signal started")) {
      return OperationResult::Failure(kAsioInvalidState, GetLastError().message);
    }

    const ASIOError result = ASIOStart();
    if (result != ASE_OK) {
      TransitionTo(DeviceLifecycleState::kFaulted, "ASIOStart failed");
      AddErrorEvent(result, "ASIOStart", IsDopMode(config_.format)
          ? "failed to start ASIO DoP carrier stream"
          : "failed to start ASIO PCM stream");
      return Fail(kAsioStartFailed, IsDopMode(config_.format)
          ? "failed to start ASIO DoP carrier stream"
          : "failed to start ASIO PCM stream");
    }
    started_ = true;
    return OperationResult::Success();
#endif
  }

  OperationResult Stop() {
    const auto current = GetState();
    if (current == DeviceLifecycleState::kRunningSignal &&
        policy_.keep_warm_after_signal) {
      force_silence_ = true;
      if (!TransitionTo(DeviceLifecycleState::kRunningSilence,
                        IsDopMode(config_.format)
                            ? "normal ASIO stop switched to valid DoP silence keep-warm"
                            : "normal ASIO stop switched to valid PCM silence keep-warm")) {
        return OperationResult::Failure(kAsioInvalidState, GetLastError().message);
      }
      return OperationResult::Success();
    }
    if (current == DeviceLifecycleState::kRunningSilence &&
        policy_.keep_warm_after_signal) {
      return OperationResult::Success();
    }

#if APTT_ENABLE_ASIO && defined(_WIN32)
    if (current == DeviceLifecycleState::kRunningSignal ||
        current == DeviceLifecycleState::kRunningSilence) {
      if (!TransitionTo(DeviceLifecycleState::kDraining,
                        "ASIO stream stopping before hold/release")) {
        return OperationResult::Failure(kAsioInvalidState, GetLastError().message);
      }
      const auto stop = StopAsioStream();
      if (!stop.ok) {
        return stop;
      }
    }
#endif

    if (policy_.release_after_drain) {
      return ReleaseAfterDrain();
    }
    if (GetState() != DeviceLifecycleState::kHeldOpen) {
      if (!TransitionTo(DeviceLifecycleState::kHeldOpen,
                        "ASIO driver held open after stop")) {
        return OperationResult::Failure(kAsioInvalidState, GetLastError().message);
      }
    }
    return OperationResult::Success();
  }

  OperationResult Reset() {
    return Fail(
        kAsioResetDisabled,
        "ASIO PCM/DoP carrier reset is disabled; use keep-warm, drain, and bounded release");
  }

  OperationResult Shutdown() {
    const auto current = GetState();
    if (current == DeviceLifecycleState::kDiscovered ||
        current == DeviceLifecycleState::kReleased) {
      return OperationResult::Success();
    }

    if (current == DeviceLifecycleState::kRunningSignal ||
        current == DeviceLifecycleState::kRunningSilence) {
      if (!TransitionTo(DeviceLifecycleState::kDraining,
                        "ASIO stream draining before release")) {
        return OperationResult::Failure(kAsioInvalidState, GetLastError().message);
      }
    }
    return ReleaseAfterDrain();
  }

  RealtimeStats GetRealtimeStats() const {
    std::lock_guard lock(stats_mutex_);
    return stats_;
  }

  BackendError GetLastError() const {
    std::lock_guard lock(error_mutex_);
    return last_error_;
  }

  DeviceLifecycleState GetState() const {
    std::lock_guard lock(state_mutex_);
    return lifecycle_state_;
  }

  std::vector<DiagnosticEvent> GetEvents() const {
    std::lock_guard lock(events_mutex_);
    return events_;
  }

 private:
  OperationResult Fail(int code, std::string message) {
    SetLastError({code, std::move(message)});
    return OperationResult::Failure(code, GetLastError().message);
  }

  void SetLastError(BackendError error) {
    std::lock_guard lock(error_mutex_);
    last_error_ = std::move(error);
  }

  bool TransitionTo(DeviceLifecycleState next, std::string message) {
    DeviceLifecycleState previous;
    {
      std::lock_guard lock(state_mutex_);
      previous = lifecycle_state_;
      LifecyclePolicy lifecycle_policy;
      lifecycle_policy.known_problem_device =
          config_.device.is_known_problem_device;
      const auto decision = EvaluateTransition(previous, next, lifecycle_policy);
      if (!decision.allowed) {
        SetLastError({kAsioInvalidState, decision.reason});
        return false;
      }
      lifecycle_state_ = next;
    }

    auto event = MakeLifecycleEvent(
        NextSequence(),
        BackendApi::kAsio,
        config_.device.stable_id,
        previous,
        next,
        std::move(message));
    event.backend_fields["hold_mode"] = ToString(config_.hold_mode);
    event.backend_fields["signal_mode"] = ToString(config_.format.signal_mode);
    event.backend_fields["keep_alive_format"] = KeepAliveFormatName(config_.format);
    event.backend_fields["reset_used"] = "false";
    event.backend_fields["repeated_asio_exit"] = "false";
    AppendEvent(std::move(event));
    SetLastError({});
    return true;
  }

  std::uint64_t NextSequence() { return ++sequence_; }

  void AppendEvent(DiagnosticEvent event) {
    std::lock_guard lock(events_mutex_);
    events_.push_back(std::move(event));
  }

  void AddPreparedEvent() {
    auto event = MakeAsioPcmPreparedEvent(
        NextSequence(),
        config_.device.stable_id,
        config_.format,
        constraints_);
    if (asio_sample_type_) {
      event.backend_fields["asio_sample_type"] = ToString(*asio_sample_type_);
    }
    event.backend_fields["driver_name"] = config_.device.driver_name;
    event.backend_fields["output_channels"] = std::to_string(output_channels_);
    event.backend_fields["sample_rate_set_result"] = sample_rate_set_result_;
    event.backend_fields["current_sample_rate"] =
        std::to_string(current_sample_rate_hz_);
    AddHighLoadDiagnosticFields(config_, event.backend_fields);
    AppendEvent(std::move(event));
  }

  void AddRuntimeEvent(std::int32_t buffer_index,
                       double callback_duration_ms,
                       bool direct_process,
                       bool output_ready_called) {
    const auto stats = GetRealtimeStats();
    if (stats.callback_count > 8 && (stats.callback_count % 50) != 0) {
      return;
    }
    auto event = MakeAsioPcmRuntimeEvent(
        NextSequence(),
        config_.device.stable_id,
        stats,
        buffer_index,
        constraints_.preferred_size,
        callback_duration_ms,
        direct_process,
        output_ready_called);
    event.backend_fields["signal_mode"] = ToString(config_.format.signal_mode);
    event.backend_fields["keep_alive_format"] =
        KeepAliveFormatName(config_.format);
    if (IsDopMode(config_.format)) {
      event.backend_fields["dop_next_marker_frame"] =
          std::to_string(dop_generator_.next_dop_frame_index());
    }
    AddHighLoadDiagnosticFields(config_, event.backend_fields);
    if (HighLoadLateCallbackJustOccurred(config_, stats)) {
      event.backend_fields["late_callback"] = "true";
      event.backend_fields["late_callback_source"] =
          "high_load_driver_callback_delay";
    }
    AppendEvent(std::move(event));
  }

  void AddErrorEvent(int code, std::string api, std::string message) {
    DiagnosticEvent event;
    event.type = DiagnosticEventType::kError;
    event.sequence = NextSequence();
    event.backend = BackendApi::kAsio;
    event.device_id = config_.device.stable_id;
    event.message = std::move(message);
    event.backend_fields["api"] = std::move(api);
    event.backend_fields["code"] = std::to_string(code);
#if APTT_ENABLE_ASIO && defined(_WIN32)
    event.backend_fields["symbol"] =
        AsioErrorSymbol(static_cast<ASIOError>(code));
#endif
    event.backend_fields["repeated_asio_exit"] = "false";
    AppendEvent(std::move(event));
  }

  OperationResult ReleaseAfterDrain() {
    const auto current = GetState();
    if (current == DeviceLifecycleState::kFaulted) {
#if APTT_ENABLE_ASIO && defined(_WIN32)
      const auto release = ReleaseAsioResources();
      if (!release.ok) {
        return release;
      }
#endif
      if (!TransitionTo(DeviceLifecycleState::kReleased,
                        "faulted ASIO resources released once")) {
        return OperationResult::Failure(kAsioInvalidState, GetLastError().message);
      }
      return OperationResult::Success();
    }

    if (current != DeviceLifecycleState::kReleasing &&
        current != DeviceLifecycleState::kReleased &&
        current != DeviceLifecycleState::kDiscovered) {
      if (!TransitionTo(DeviceLifecycleState::kReleasing,
                        "ASIO resources releasing after drain/cooldown")) {
        return OperationResult::Failure(kAsioInvalidState, GetLastError().message);
      }
    }

    if (policy_.release_cooldown_ms > 0) {
      std::this_thread::sleep_for(
          std::chrono::milliseconds(policy_.release_cooldown_ms));
    }

#if APTT_ENABLE_ASIO && defined(_WIN32)
    const auto release = ReleaseAsioResources();
    if (!release.ok) {
      TransitionTo(DeviceLifecycleState::kFaulted,
                   "ASIO resource release failed");
      return release;
    }
#endif

    if (GetState() != DeviceLifecycleState::kReleased) {
      if (!TransitionTo(DeviceLifecycleState::kReleased,
                        "ASIO driver and buffers released once")) {
        return OperationResult::Failure(kAsioInvalidState, GetLastError().message);
      }
    }
    return OperationResult::Success();
  }

#if APTT_ENABLE_ASIO && defined(_WIN32)
  OperationResult InitializeAsioDriver() {
    if (!TryLoadAsioDriverName(config_.device.display_name) &&
        !TryLoadAsioDriverName(config_.device.driver_name)) {
      TransitionTo(DeviceLifecycleState::kFaulted, "ASIO driver load failed");
      return Fail(kAsioDriverLoadFailed, "failed to load selected ASIO driver");
    }
    driver_loaded_ = true;

    driver_info_ = {};
    driver_info_.asioVersion = 2;
    const ASIOError init_result = ASIOInit(&driver_info_);
    if (init_result != ASE_OK) {
      TransitionTo(DeviceLifecycleState::kFaulted, "ASIOInit failed");
      AddErrorEvent(init_result, "ASIOInit", "failed to initialize ASIO driver");
      ReleaseAsioResources();
      return Fail(kAsioDriverInitFailed, "failed to initialize ASIO driver");
    }

    long input_channels = 0;
    long output_channels = 0;
    ASIOError query_result = ASIOGetChannels(&input_channels, &output_channels);
    if (query_result != ASE_OK || output_channels <= 0 ||
        output_channels < static_cast<long>(config_.format.channels.channel_count)) {
      TransitionTo(DeviceLifecycleState::kFaulted, "ASIOGetChannels failed");
      AddErrorEvent(
          query_result,
          "ASIOGetChannels",
          "ASIO driver does not expose enough output channels");
      ReleaseAsioResources();
      return Fail(kAsioDriverQueryFailed,
                  "ASIO driver does not expose enough output channels");
    }
    output_channels_ = output_channels;

    const ASIOSampleRate requested_rate =
        static_cast<ASIOSampleRate>(config_.format.sample_rate_hz);
    const ASIOError can_rate = ASIOCanSampleRate(requested_rate);
    if (can_rate != ASE_OK) {
      TransitionTo(DeviceLifecycleState::kFaulted, "ASIOCanSampleRate failed");
      AddErrorEvent(can_rate, "ASIOCanSampleRate",
                    "requested ASIO sample rate is not supported");
      ReleaseAsioResources();
      return Fail(kAsioSampleRateFailed,
                  "requested ASIO sample rate is not supported");
    }

    ASIOSampleRate current_rate = 0.0;
    query_result = ASIOGetSampleRate(&current_rate);
    if (query_result != ASE_OK || current_rate <= 0.0) {
      TransitionTo(DeviceLifecycleState::kFaulted, "ASIOGetSampleRate failed");
      AddErrorEvent(query_result, "ASIOGetSampleRate",
                    "failed to query ASIO sample rate");
      ReleaseAsioResources();
      return Fail(kAsioSampleRateFailed, "failed to query ASIO sample rate");
    }
    current_sample_rate_hz_ = static_cast<double>(current_rate);
    sample_rate_set_result_ = "unchanged";
    if (std::llround(current_rate) !=
        static_cast<long long>(config_.format.sample_rate_hz)) {
      const ASIOError set_result = ASIOSetSampleRate(requested_rate);
      if (set_result != ASE_OK) {
        TransitionTo(DeviceLifecycleState::kFaulted, "ASIOSetSampleRate failed");
        AddErrorEvent(set_result, "ASIOSetSampleRate",
                      "failed to set requested ASIO sample rate");
        ReleaseAsioResources();
        return Fail(kAsioSampleRateFailed,
                    "failed to set requested ASIO sample rate");
      }
      sample_rate_set_result_ = "set-once";
      current_sample_rate_hz_ =
          static_cast<double>(config_.format.sample_rate_hz);
    }

    query_result = ASIOGetBufferSize(
        &constraints_.min_size,
        &constraints_.max_size,
        &constraints_.preferred_size,
        &constraints_.granularity);
    if (query_result != ASE_OK || constraints_.preferred_size <= 0) {
      TransitionTo(DeviceLifecycleState::kFaulted, "ASIOGetBufferSize failed");
      AddErrorEvent(query_result, "ASIOGetBufferSize",
                    "failed to query ASIO buffer constraints");
      ReleaseAsioResources();
      return Fail(kAsioDriverQueryFailed,
                  "failed to query ASIO buffer constraints");
    }

    constraints_.output_ready_supported = ASIOOutputReady() == ASE_OK;
    callbacks_.bufferSwitch = &AsioBufferSwitch;
    callbacks_.sampleRateDidChange = &AsioSampleRateChanged;
    callbacks_.asioMessage = &AsioMessages;
    callbacks_.bufferSwitchTimeInfo = &AsioBufferSwitchTimeInfo;

    buffer_infos_.clear();
    buffer_infos_.resize(config_.format.channels.channel_count);
    for (std::uint32_t channel = 0; channel < config_.format.channels.channel_count;
         ++channel) {
      auto& info = buffer_infos_[channel];
      info.isInput = ASIOFalse;
      info.channelNum = static_cast<long>(channel);
      info.buffers[0] = nullptr;
      info.buffers[1] = nullptr;
    }

    SetActiveAsioCallbackSink(this);
    const ASIOError buffer_result = ASIOCreateBuffers(
        buffer_infos_.data(),
        static_cast<long>(buffer_infos_.size()),
        constraints_.preferred_size,
        &callbacks_);
    if (buffer_result != ASE_OK) {
      SetActiveAsioCallbackSink(nullptr);
      TransitionTo(DeviceLifecycleState::kFaulted, "ASIOCreateBuffers failed");
      AddErrorEvent(buffer_result, "ASIOCreateBuffers",
                    "failed to create ASIO output buffers");
      ReleaseAsioResources();
      return Fail(kAsioBufferCreateFailed,
                  "failed to create ASIO output buffers");
    }
    buffers_created_ = true;

    channel_infos_.clear();
    channel_infos_.resize(buffer_infos_.size());
    for (std::size_t index = 0; index < buffer_infos_.size(); ++index) {
      auto& info = channel_infos_[index];
      info.channel = buffer_infos_[index].channelNum;
      info.isInput = ASIOFalse;
      const ASIOError channel_result = ASIOGetChannelInfo(&info);
      if (channel_result != ASE_OK) {
        TransitionTo(DeviceLifecycleState::kFaulted, "ASIOGetChannelInfo failed");
        AddErrorEvent(channel_result, "ASIOGetChannelInfo",
                      "failed to query ASIO output channel sample type");
        ReleaseAsioResources();
        return Fail(kAsioDriverQueryFailed,
                    "failed to query ASIO output channel sample type");
      }
      const auto sample_type = AsioSampleTypeFromSdk(info.type);
      if (!sample_type) {
        TransitionTo(DeviceLifecycleState::kFaulted,
                     "unsupported ASIO PCM carrier sample type");
        AddErrorEvent(static_cast<int>(info.type), "ASIOGetChannelInfo",
                      "unsupported ASIO PCM carrier sample type");
        ReleaseAsioResources();
        return Fail(kAsioUnsupportedSampleType,
                    "unsupported ASIO PCM carrier sample type");
      }
      if (!asio_sample_type_) {
        asio_sample_type_ = sample_type;
      } else if (*asio_sample_type_ != *sample_type) {
        TransitionTo(DeviceLifecycleState::kFaulted,
                     "mixed ASIO output sample types are not supported");
        ReleaseAsioResources();
        return Fail(kAsioUnsupportedSampleType,
                    "mixed ASIO output sample types are not supported");
      }
    }

    const auto requested_sample_type = AsioSampleTypeForFormat(config_.format);
    if (!requested_sample_type || !asio_sample_type_ ||
        *requested_sample_type != *asio_sample_type_) {
      TransitionTo(DeviceLifecycleState::kFaulted,
                   IsDopMode(config_.format)
                       ? "selected ASIO DoP carrier sample type does not match driver output"
                       : "selected ASIO PCM sample type does not match driver output");
      ReleaseAsioResources();
      return Fail(
          kAsioUnsupportedSampleType,
          IsDopMode(config_.format)
              ? "selected ASIO DoP carrier sample type does not match driver output"
              : "selected ASIO PCM sample type does not match driver output");
    }

    query_result = ASIOGetLatencies(
        &constraints_.input_latency,
        &constraints_.output_latency);
    if (query_result != ASE_OK) {
      AddErrorEvent(query_result, "ASIOGetLatencies",
                    "ASIO latency query failed after buffer creation");
    }

    {
      std::lock_guard lock(stats_mutex_);
      stats_.expected_callback_interval_ms =
          1000.0 * static_cast<double>(constraints_.preferred_size) /
          static_cast<double>(config_.format.sample_rate_hz);
    }

    if (!TransitionTo(DeviceLifecycleState::kPrepared,
                      IsDopMode(config_.format)
                          ? "ASIO buffers created once for selected DoP carrier profile"
                          : "ASIO buffers created once for selected PCM profile")) {
      ReleaseAsioResources();
      return OperationResult::Failure(kAsioInvalidState, GetLastError().message);
    }
    AddPreparedEvent();
    return OperationResult::Success();
  }

  OperationResult StopAsioStream() {
    if (!started_) {
      return OperationResult::Success();
    }
    const ASIOError stop_result = ASIOStop();
    if (stop_result != ASE_OK) {
      AddErrorEvent(stop_result, "ASIOStop", "failed to stop ASIO stream");
      return Fail(kAsioStopFailed, "failed to stop ASIO stream");
    }
    started_ = false;
    return OperationResult::Success();
  }

  OperationResult ReleaseAsioResources() {
    const auto stop = StopAsioStream();
    if (!stop.ok) {
      return stop;
    }
    SetActiveAsioCallbackSink(nullptr);

    if (buffers_created_) {
      const ASIOError dispose_result = ASIODisposeBuffers();
      if (dispose_result != ASE_OK) {
        AddErrorEvent(dispose_result, "ASIODisposeBuffers",
                      "failed to dispose ASIO buffers");
        return Fail(kAsioDisposeFailed, "failed to dispose ASIO buffers");
      }
      buffers_created_ = false;
      buffer_infos_.clear();
      channel_infos_.clear();
    }

    if (driver_loaded_) {
      const ASIOError exit_result = ASIOExit();
      if (exit_result != ASE_OK) {
        AddErrorEvent(exit_result, "ASIOExit",
                      "failed to release ASIO driver");
        return Fail(kAsioExitFailed, "failed to release ASIO driver");
      }
      driver_loaded_ = false;
    }
    return OperationResult::Success();
  }

  void OnAsioBufferSwitch(long buffer_index,
                          bool direct_process,
                          bool) override {
    FillOutputBuffer(buffer_index,
                     true,
                     direct_process,
                     policy_.uses_output_ready_if_supported);
  }

  void OnAsioSampleRateChanged(double sample_rate) override {
    DiagnosticEvent event;
    event.type = DiagnosticEventType::kRuntimeStats;
    event.sequence = NextSequence();
    event.backend = BackendApi::kAsio;
    event.device_id = config_.device.stable_id;
    event.message = "ASIO sampleRateDidChange callback";
    event.backend_fields["sample_rate_hz"] = std::to_string(sample_rate);
    event.backend_fields["driver_callback"] = "sampleRateDidChange";
    AppendEvent(std::move(event));
  }

  long OnAsioMessage(long selector, long value) override {
    DiagnosticEvent event;
    event.type = DiagnosticEventType::kRuntimeStats;
    event.sequence = NextSequence();
    event.backend = BackendApi::kAsio;
    event.device_id = config_.device.stable_id;
    event.message = "ASIO asioMessage callback";
    event.backend_fields["selector"] = std::to_string(selector);
    event.backend_fields["value"] = std::to_string(value);
    event.backend_fields["driver_callback"] = "asioMessage";

    long result = 0;
    switch (selector) {
      case kAsioSelectorSupported:
        result = value == kAsioResetRequest ||
                 value == kAsioEngineVersion ||
                 value == kAsioResyncRequest ||
                 value == kAsioLatenciesChanged ||
                 value == kAsioSupportsTimeInfo ||
                 value == kAsioOverload
                     ? 1
                     : 0;
        break;
      case kAsioEngineVersion:
        result = 2;
        break;
      case kAsioSupportsTimeInfo:
        result = 1;
        break;
      case kAsioResetRequest:
        event.backend_fields["reset_request_deferred"] = "true";
        {
          std::lock_guard lock(stats_mutex_);
          ++stats_.discontinuity_count;
        }
        result = 1;
        break;
      case kAsioResyncRequest:
        event.backend_fields["resync_request"] = "true";
        {
          std::lock_guard lock(stats_mutex_);
          ++stats_.discontinuity_count;
        }
        result = 1;
        break;
      case kAsioLatenciesChanged:
        event.backend_fields["latencies_changed"] = "true";
        result = 1;
        break;
      case kAsioOverload:
        event.backend_fields["overload"] = "true";
        {
          std::lock_guard lock(stats_mutex_);
          ++stats_.underrun_count;
        }
        result = 1;
        break;
      default:
        result = 0;
        break;
    }
    event.backend_fields["result"] = std::to_string(result);
    AppendEvent(std::move(event));
    return result;
  }

  bool WriteDopSignalAndSilenceToAsioPlanar(
      long buffer_index,
      std::uint32_t total_frames,
      std::uint32_t signal_frames,
      std::size_t bytes_per_channel) {
    if (!asio_sample_type_ ||
        *asio_sample_type_ != AsioPcmSampleType::kInt24In32Lsb) {
      AddErrorEvent(kAsioUnsupportedSampleType,
                    "ASIOGetChannelInfo",
                    "ASIO DoP carrier requires ASIOSTInt32LSB24 output");
      SetLastError({kAsioUnsupportedSampleType,
                    "ASIO DoP carrier requires ASIOSTInt32LSB24 output"});
      return false;
    }

    const std::uint32_t channel_count = config_.format.channels.channel_count;
    const DopConfig dop_config = DopConfigFromFormat(config_.format);
    std::vector<std::vector<std::uint8_t>> planar(
        channel_count,
        std::vector<std::uint8_t>(bytes_per_channel, 0));

    auto copy_segment =
        [&](const std::vector<std::uint8_t>& interleaved,
            std::uint32_t start_frame) -> bool {
      const auto segment =
          ConvertInterleavedDop24In32ToAsioPlanar(interleaved, channel_count);
      if (segment.size() != planar.size()) {
        AddErrorEvent(kAsioInvalidArgument,
                      "ConvertInterleavedDop24In32ToAsioPlanar",
                      "generated ASIO DoP carrier bytes are not channel-aligned");
        SetLastError({kAsioInvalidArgument,
                      "generated ASIO DoP carrier bytes are not channel-aligned"});
        return false;
      }
      const std::size_t destination =
          static_cast<std::size_t>(start_frame) *
          AsioBytesPerSample(AsioPcmSampleType::kInt24In32Lsb);
      for (std::size_t channel = 0; channel < segment.size(); ++channel) {
        if (destination + segment[channel].size() > planar[channel].size()) {
          AddErrorEvent(kAsioInvalidArgument,
                        "DopSineGenerator",
                        "generated ASIO DoP carrier bytes exceed output buffer");
          SetLastError({kAsioInvalidArgument,
                        "generated ASIO DoP carrier bytes exceed output buffer"});
          return false;
        }
        std::memcpy(planar[channel].data() + destination,
                    segment[channel].data(),
                    segment[channel].size());
      }
      return true;
    };

    if (signal_frames > 0) {
      DopSineConfig sine_config;
      sine_config.dop = dop_config;
      sine_config.frequency_hz = config_.frequency_hz;
      sine_config.amplitude_dbfs = config_.amplitude_dbfs;
      auto signal = dop_generator_.GenerateSine(sine_config, signal_frames);
      if (!signal.ok) {
        AddErrorEvent(kAsioInvalidArgument,
                      "DopSineGenerator::GenerateSine",
                      signal.error);
        SetLastError({kAsioInvalidArgument, signal.error});
        return false;
      }
      if (!copy_segment(signal.bytes, 0)) {
        return false;
      }
    }

    const std::uint32_t silence_frames = total_frames - signal_frames;
    if (silence_frames > 0) {
      auto silence = dop_generator_.GenerateSilence(dop_config, silence_frames);
      if (!silence.ok) {
        AddErrorEvent(kAsioInvalidArgument,
                      "DopSineGenerator::GenerateSilence",
                      silence.error);
        SetLastError({kAsioInvalidArgument, silence.error});
        return false;
      }
      if (!copy_segment(silence.bytes, signal_frames)) {
        return false;
      }
    }

    for (std::size_t channel = 0; channel < planar.size(); ++channel) {
      std::memcpy(buffer_infos_[channel].buffers[buffer_index],
                  planar[channel].data(),
                  bytes_per_channel);
    }
    return true;
  }

  bool FillOutputBuffer(long buffer_index,
                        bool count_stats,
                        bool direct_process,
                        bool allow_output_ready) {
    if (buffer_index < 0 || buffer_index > 1 || !asio_sample_type_) {
      return false;
    }
    const auto before = std::chrono::steady_clock::now();
    ApplyHighLoadRenderDelay(config_, GetRealtimeStats().callback_count);
    const std::uint32_t frame_count =
        static_cast<std::uint32_t>(constraints_.preferred_size);
    const std::uint32_t channel_count = config_.format.channels.channel_count;
    const std::size_t bytes_per_channel =
        static_cast<std::size_t>(frame_count) *
        AsioBytesPerSample(*asio_sample_type_);

    for (auto& buffer : buffer_infos_) {
      if (buffer.buffers[buffer_index] == nullptr) {
        return false;
      }
      std::memset(buffer.buffers[buffer_index], 0, bytes_per_channel);
    }

    const std::uint64_t written = signal_frames_written_.load();
    const bool silence_only = force_silence_ || written >= signal_frame_target_;
    const std::uint32_t signal_frames = silence_only
        ? 0
        : static_cast<std::uint32_t>(std::min<std::uint64_t>(
              frame_count,
              signal_frame_target_ - written));

    if (IsDopMode(config_.format)) {
      if (!WriteDopSignalAndSilenceToAsioPlanar(
              buffer_index,
              frame_count,
              signal_frames,
              bytes_per_channel)) {
        return false;
      }
      signal_frames_written_ += signal_frames;
    } else if (signal_frames > 0) {
      PcmSineConfig sine_config;
      sine_config.sample_rate_hz = config_.format.sample_rate_hz;
      sine_config.channel_count = channel_count;
      sine_config.frequency_hz = config_.frequency_hz;
      sine_config.amplitude_dbfs = config_.amplitude_dbfs;
      if (config_.left_channel_enabled && !config_.right_channel_enabled) {
        sine_config.channel_assignment = ChannelAssignment::kLeftOnly;
      } else if (!config_.left_channel_enabled && config_.right_channel_enabled) {
        sine_config.channel_assignment = ChannelAssignment::kRightOnly;
      }
      sine_config.invert_right = config_.invert_right_phase;
      sine_config.right_channel_phase_offset_degrees =
          config_.right_channel_phase_offset_degrees;
      auto samples =
          GenerateInterleavedSilenceFloat32(frame_count, channel_count);
      auto signal = generator_.GenerateInterleavedFloat32(
          sine_config,
          signal_frames);
      std::copy(signal.begin(), signal.end(), samples.begin());
      const auto planar = ConvertFloat32InterleavedToAsioPlanar(
          samples,
          channel_count,
          *asio_sample_type_);
      if (planar.size() != buffer_infos_.size()) {
        return false;
      }
      for (std::size_t channel = 0; channel < planar.size(); ++channel) {
        std::memcpy(
            buffer_infos_[channel].buffers[buffer_index],
            planar[channel].data(),
            std::min(planar[channel].size(), bytes_per_channel));
      }
      signal_frames_written_ += signal_frames;
    }

    bool output_ready_called = false;
    if (allow_output_ready && constraints_.output_ready_supported) {
      output_ready_called = ASIOOutputReady() == ASE_OK;
    }

    if (count_stats) {
      {
        std::lock_guard lock(stats_mutex_);
        stats_.frames_generated += signal_frames;
        stats_.frames_submitted += frame_count;
        stats_.frames_accepted += frame_count;
        ++stats_.callback_count;
        const auto now = std::chrono::steady_clock::now();
        const double interval_ms =
            std::chrono::duration<double, std::milli>(
                now - last_callback_time_).count();
        stats_.last_callback_interval_ms = interval_ms;
        stats_.max_callback_delay_ms =
            std::max(stats_.max_callback_delay_ms, interval_ms);
        CountHighLoadLateCallbackIfNeeded(config_, stats_);
        last_callback_time_ = now;
      }
      const auto after = std::chrono::steady_clock::now();
      const double duration_ms =
          std::chrono::duration<double, std::milli>(after - before).count();
      AddRuntimeEvent(
          static_cast<std::int32_t>(buffer_index),
          duration_ms,
          direct_process,
          output_ready_called);
    }

    if (GetState() == DeviceLifecycleState::kRunningSignal &&
        signal_frames_written_.load() >= signal_frame_target_) {
      if (policy_.keep_warm_after_signal) {
        force_silence_ = true;
        TransitionTo(DeviceLifecycleState::kRunningSilence,
                     IsDopMode(config_.format)
                         ? "signal ended; ASIO valid DoP silence keep-warm is running"
                         : "signal ended; ASIO valid PCM silence keep-warm is running");
      } else {
        TransitionTo(DeviceLifecycleState::kHeldOpen,
                     "signal ended; ASIO driver remains initialized");
      }
    }
    return true;
  }
#endif

  mutable std::mutex error_mutex_;
  mutable std::mutex state_mutex_;
  mutable std::mutex stats_mutex_;
  mutable std::mutex events_mutex_;
  BackendError last_error_;
  DeviceLifecycleState lifecycle_state_ = DeviceLifecycleState::kDiscovered;
  PlaybackConfig config_;
  AsioPcmPolicy policy_;
  AsioBufferConstraints constraints_;
  RealtimeStats stats_;
  std::vector<DiagnosticEvent> events_;
  std::uint64_t sequence_ = 0;
  std::atomic<std::uint64_t> signal_frames_written_{0};
  std::uint64_t signal_frame_target_ = 0;
  std::atomic<bool> force_silence_{false};
  PcmSineGenerator generator_;
  DopSineGenerator dop_generator_;
  std::chrono::steady_clock::time_point last_callback_time_ =
      std::chrono::steady_clock::now();
  std::optional<AsioPcmSampleType> asio_sample_type_;
  long output_channels_ = 0;
  double current_sample_rate_hz_ = 0.0;
  std::string sample_rate_set_result_ = "not-queried";

#if APTT_ENABLE_ASIO && defined(_WIN32)
  ASIODriverInfo driver_info_{};
  ASIOCallbacks callbacks_{};
  std::vector<ASIOBufferInfo> buffer_infos_;
  std::vector<ASIOChannelInfo> channel_infos_;
  bool driver_loaded_ = false;
  bool buffers_created_ = false;
  bool started_ = false;
#endif
};

AsioPcmBackend::AsioPcmBackend()
    : impl_(std::make_unique<Impl>()) {}

AsioPcmBackend::~AsioPcmBackend() = default;

BackendApi AsioPcmBackend::api() const {
  return impl_->Api();
}

DeviceList AsioPcmBackend::enumerateDevices() {
  return impl_->EnumerateDevices();
}

FormatProbeResult AsioPcmBackend::probeFormats(const DeviceInfo& device) {
  return impl_->ProbeFormats(device);
}

FormatProbeResult AsioPcmBackend::probeDopFormats(const DeviceInfo& device) {
  DopConfig requested_dop;
  requested_dop.dsd_rate_multiplier = 64;
  requested_dop.channel_count = 2;
  return impl_->ProbeDopFormats(device, requested_dop);
}

FormatProbeResult AsioPcmBackend::probeDopFormats(
    const DeviceInfo& device,
    const DopConfig& requested_dop) {
  return impl_->ProbeDopFormats(device, requested_dop);
}

OperationResult AsioPcmBackend::initialize(const PlaybackConfig& config) {
  return impl_->Initialize(config);
}

OperationResult AsioPcmBackend::start() {
  return impl_->Start();
}

OperationResult AsioPcmBackend::stop() {
  return impl_->Stop();
}

OperationResult AsioPcmBackend::reset() {
  return impl_->Reset();
}

RealtimeStats AsioPcmBackend::getRealtimeStats() const {
  return impl_->GetRealtimeStats();
}

BackendError AsioPcmBackend::getLastError() const {
  return impl_->GetLastError();
}

OperationResult AsioPcmBackend::shutdown() {
  return impl_->Shutdown();
}

DeviceLifecycleState AsioPcmBackend::lifecycle_state() const {
  return impl_->GetState();
}

std::vector<DiagnosticEvent> AsioPcmBackend::diagnostic_events() const {
  return impl_->GetEvents();
}

}  // namespace aptt
