#pragma once

#include <cstdint>
#include <optional>
#include <string>
#include <vector>

#include "core/device_discovery.h"

namespace aptt {

struct KernelStreamingStableIdParts {
  std::string filter_symbolic_link;
  std::uint32_t pin_id = 0;
};

struct KernelStreamingFormatProbeRequest {
  std::string stable_id;
  std::vector<FormatDescriptor> candidate_formats;
  bool create_pin_for_exact_format = false;
  bool detect_wavert_with_pin_probe = false;
  std::uint32_t max_candidate_formats = 128;
};

struct KernelStreamingStreamingModelMetadata {
  bool supports_standard_streaming = false;
  bool supports_looped_streaming = false;
  std::string supports_wavert_rtaudio_properties = "unknown";
  std::string accepts_wavert_notification_buffer = "unknown";
  std::string streaming_model = "unknown";
  std::string playback_implementation = "unimplemented";
  std::string pin_interface_set = "unknown";
  std::string pin_interface_id = "unknown";
};

FormatDescriptor KernelStreamingPcmCandidate(std::uint32_t sample_rate_hz,
                                             SampleType sample_type,
                                             std::uint32_t channel_count);
std::vector<FormatDescriptor> KernelStreamingDefaultPcmCandidates();

std::string KernelStreamingStableId(std::string filter_symbolic_link,
                                    std::uint32_t pin_id);
std::optional<KernelStreamingStableIdParts> ParseKernelStreamingStableId(
    const std::string& stable_id);

std::string KernelStreamingStatusSymbol(std::int64_t raw_status);
CapabilitySupport KernelStreamingSupportFromNtStatus(
    std::int64_t raw_status);
KernelStreamingStreamingModelMetadata ClassifyKernelStreamingStreamingModel(
    bool supports_standard_streaming,
    bool supports_looped_streaming,
    std::string supports_wavert_rtaudio_properties,
    std::string pin_interface_set = "unknown",
    std::string pin_interface_id = "unknown",
    std::string accepts_wavert_notification_buffer = "unknown");

DeviceCapabilitySnapshot MakeKernelStreamingPinSnapshot(
    std::string filter_symbolic_link,
    std::uint32_t pin_id,
    std::string dataflow,
    std::string communication,
    std::uint32_t data_range_count,
    DeviceAvailability availability);

DiscoverySnapshot EnumerateKernelStreamingDevices();
DeviceCapabilitySnapshot ProbeKernelStreamingPinFormats(
    const KernelStreamingFormatProbeRequest& request);

}  // namespace aptt
