// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_MEDIA_AUDIO_AUDIO_CORE_TESTING_FAKE_AUDIO_DRIVER_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_TESTING_FAKE_AUDIO_DRIVER_H_

#include <fuchsia/hardware/audio/cpp/fidl.h>
#include <lib/async/cpp/time.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fit/result.h>
#include <lib/fzl/vmo-mapper.h>
#include <lib/zx/channel.h>
#include <lib/zx/vmo.h>
#include <zircon/device/audio.h>

#include <cstring>
#include <optional>

#include "src/media/audio/lib/test/message_transceiver.h"

namespace media::audio::testing {

class FakeAudioDriverV1 {
 public:
  FakeAudioDriverV1(zx::channel channel, async_dispatcher_t* dispatcher);

  fzl::VmoMapper CreateRingBuffer(size_t size);

  // Starts an async wait that will process messages as they're received.
  void Start();

  // Cease processing messages as they're received.
  void Stop();

  // Processes a single message from the driver channel and returns the |audio_cmd_t| that was
  // processed.
  //
  // If there are no messages to process, ZX_ERR_SHOULD_WAIT is returned as an error.
  fit::result<audio_cmd_t, zx_status_t> Step();

  // Processes a single message from the driver ring buffer channel and returns the |audio_cmd_t|
  // that was processed.
  //
  // If there are no messages to process, ZX_ERR_SHOULD_WAIT is returned as an error.
  fit::result<audio_cmd_t, zx_status_t> StepRingBuffer();

  struct SelectedFormat {
    uint32_t frames_per_second;
    audio_sample_format_t sample_format;
    uint16_t channels;
  };

  void set_stream_unique_id(const audio_stream_unique_id_t& uid) {
    std::memcpy(uid_.data, uid.data, sizeof(uid.data));
  }
  void set_device_manufacturer(std::string mfgr) { manufacturer_ = std::move(mfgr); }
  void set_device_product(std::string product) { product_ = std::move(product); }
  void set_gain(float gain) { cur_gain_ = gain; }
  void set_gain_limits(float min_gain, float max_gain) {
    gain_limits_ = std::make_pair(min_gain, max_gain);
  }
  void set_can_agc(bool can_agc) { can_agc_ = can_agc; }
  void set_cur_agc(bool cur_agc) { cur_agc_ = cur_agc; }
  void set_can_mute(bool can_mute) { can_mute_ = can_mute; }
  void set_cur_mute(bool cur_mute) { cur_mute_ = cur_mute; }
  void set_formats(std::vector<audio_stream_format_range_t> formats) {
    formats_ = std::move(formats);
  }
  void set_clock_domain(uint32_t clock_domain) { clock_domain_ = clock_domain; }
  void set_hardwired(bool hardwired) { hardwired_ = hardwired; }
  void set_plugged(bool plugged) { plugged_ = plugged; }
  void set_fifo_depth(uint32_t fifo_depth) { fifo_depth_ = fifo_depth; }
  void set_external_delay(zx::duration external_delay) { external_delay_ = external_delay; }

  void SendPositionNotification(zx::time timestamp, uint32_t position);

  // |true| after an |audio_rb_cmd_start| is received, until an |audio_rb_cmd_stop| is received.
  bool is_running() const { return is_running_; }
  zx::time mono_start_time() const { return mono_start_time_; }

  // The 'selected format' for the driver, chosen with a |AUDIO_STREAM_CMD_SET_FORMAT| command.
  //
  // The returned optional will be empty if no |AUDIO_STREAM_CMD_SET_FORMAT| command has been
  // received.
  std::optional<SelectedFormat> selected_format() const { return selected_format_; }

 private:
  void OnInboundStreamMessage(test::MessageTransceiver::Message message);
  void OnInboundStreamError(zx_status_t status);
  void HandleCommandGetUniqueId(const audio_stream_cmd_get_unique_id_req_t& request);
  void HandleCommandGetString(const audio_stream_cmd_get_string_req_t& request);
  void HandleCommandGetGain(const audio_stream_cmd_get_gain_req_t& request);
  void HandleCommandSetGain(const audio_stream_cmd_set_gain_req_t& request);
  void HandleCommandGetFormats(const audio_stream_cmd_get_formats_req_t& request);
  void HandleCommandSetFormat(const audio_stream_cmd_set_format_req_t& request);
  void HandleCommandPlugDetect(const audio_stream_cmd_plug_detect_req_t& request);
  void HandleCommandGetClockDomain(const audio_stream_cmd_get_clock_domain_req_t& request);

  void OnInboundRingBufferMessage(test::MessageTransceiver::Message message);
  void OnInboundRingBufferError(zx_status_t status);
  void HandleCommandGetFifoDepth(audio_rb_cmd_get_fifo_depth_req_t& request);
  void HandleCommandGetBuffer(audio_rb_cmd_get_buffer_req_t& request);
  void HandleCommandStart(audio_rb_cmd_start_req_t& request);
  void HandleCommandStop(audio_rb_cmd_stop_req_t& request);

  audio_stream_unique_id_t uid_ = {};
  std::string manufacturer_ = "default manufacturer";
  std::string product_ = "default product";
  float cur_gain_ = 0.0f;
  std::pair<float, float> gain_limits_{-160.0f, 3.0f};
  bool can_agc_ = true;
  bool cur_agc_ = false;
  bool can_mute_ = true;
  bool cur_mute_ = false;
  std::vector<audio_stream_format_range_t> formats_{{
      .sample_formats = AUDIO_SAMPLE_FORMAT_16BIT,
      .min_frames_per_second = 48000,
      .max_frames_per_second = 48000,
      .min_channels = 2,
      .max_channels = 2,
      .flags = ASF_RANGE_FLAG_FPS_48000_FAMILY,
  }};
  // fuchsia::hardware::audio::CLOCK_DOMAIN_MONOTONIC is not defined for AudioDriverV1 types.
  uint32_t clock_domain_ = 0;

  size_t ring_buffer_size_;
  zx::vmo ring_buffer_;

  uint32_t fifo_depth_ = 0;
  zx::duration external_delay_{zx::nsec(0)};
  bool hardwired_ = true;
  bool plugged_ = true;

  std::optional<SelectedFormat> selected_format_;

  bool is_running_ = false;
  zx::time mono_start_time_{0};

  async_dispatcher_t* dispatcher_;
  bool is_stopped_ = true;
  test::MessageTransceiver stream_transceiver_;
  test::MessageTransceiver ring_buffer_transceiver_;

  audio_cmd_t last_stream_command_ = 0;
  audio_cmd_t last_ring_buffer_command_ = 0;

  uint32_t notifications_per_ring_;
  zx::time position_notify_timestamp_mono_;
  uint32_t position_notify_position_bytes_ = 0;
};

class FakeAudioDriverV2 : public fuchsia::hardware::audio::StreamConfig,
                          public fuchsia::hardware::audio::RingBuffer {
 public:
  FakeAudioDriverV2(zx::channel channel, async_dispatcher_t* dispatcher);

  fzl::VmoMapper CreateRingBuffer(size_t size);
  void Start();
  void Stop();

  void set_stream_unique_id(const audio_stream_unique_id_t& uid) {
    std::memcpy(uid_.data, uid.data, sizeof(uid.data));
  }
  void set_device_manufacturer(std::string mfgr) { manufacturer_ = std::move(mfgr); }
  void set_device_product(std::string product) { product_ = std::move(product); }
  void set_gain(float gain) { cur_gain_ = gain; }
  void set_gain_limits(float min_gain, float max_gain) {
    gain_limits_ = std::make_pair(min_gain, max_gain);
  }
  void set_can_agc(bool can_agc) { can_agc_ = can_agc; }
  void set_cur_agc(bool cur_agc) { cur_agc_ = cur_agc; }
  void set_can_mute(bool can_mute) { can_mute_ = can_mute; }
  void set_cur_mute(bool cur_mute) { cur_mute_ = cur_mute; }
  void set_formats(fuchsia::hardware::audio::PcmSupportedFormats formats) {
    formats_ = std::move(formats);
  }
  void set_clock_domain(uint32_t clock_domain) { clock_domain_ = clock_domain; }
  void set_plugged(bool plugged) { plugged_ = plugged; }
  void set_fifo_depth(uint32_t fifo_depth) { fifo_depth_ = fifo_depth; }
  void set_external_delay(zx::duration external_delay) { external_delay_ = external_delay; }

  void SendPositionNotification(zx::time timestamp, uint32_t position);

  // |true| after an |audio_rb_cmd_start| is received, until an |audio_rb_cmd_stop| is received.
  bool is_running() const { return is_running_; }
  zx::time mono_start_time() const { return mono_start_time_; }

  // The 'selected format' for the driver.
  // The returned optional will be empty if no |CreateRingBuffer| command has been received.
  std::optional<fuchsia::hardware::audio::PcmFormat> selected_format() const {
    return selected_format_;
  }

 private:
  // fuchsia hardware audio StreamConfig Interface
  void GetProperties(fuchsia::hardware::audio::StreamConfig::GetPropertiesCallback callback) final;
  void GetSupportedFormats(
      fuchsia::hardware::audio::StreamConfig::GetSupportedFormatsCallback callback) final;
  void CreateRingBuffer(
      fuchsia::hardware::audio::Format format,
      ::fidl::InterfaceRequest<fuchsia::hardware::audio::RingBuffer> ring_buffer) final;
  void WatchGainState(
      fuchsia::hardware::audio::StreamConfig::WatchGainStateCallback callback) final;
  void SetGain(fuchsia::hardware::audio::GainState target_state) final;
  void WatchPlugState(
      fuchsia::hardware::audio::StreamConfig::WatchPlugStateCallback callback) final;

  // fuchsia hardware audio RingBuffer Interface
  void GetProperties(fuchsia::hardware::audio::RingBuffer::GetPropertiesCallback callback) final;
  void WatchClockRecoveryPositionInfo(
      fuchsia::hardware::audio::RingBuffer::WatchClockRecoveryPositionInfoCallback callback) final;
  void GetVmo(uint32_t min_frames, uint32_t clock_recovery_notifications_per_ring,
              fuchsia::hardware::audio::RingBuffer::GetVmoCallback callback) final;
  void Start(fuchsia::hardware::audio::RingBuffer::StartCallback callback) final;
  void Stop(fuchsia::hardware::audio::RingBuffer::StopCallback callback) final;

  void PositionNotification();

  audio_stream_unique_id_t uid_ = {};
  std::string manufacturer_ = "default manufacturer";
  std::string product_ = "default product";
  float cur_gain_ = 0.0f;
  std::pair<float, float> gain_limits_{-160.0f, 3.0f};
  bool can_agc_ = true;
  bool cur_agc_ = false;
  bool can_mute_ = true;
  bool cur_mute_ = false;
  bool plug_state_sent_ = false;
  bool gain_state_sent_ = false;
  fuchsia::hardware::audio::PcmSupportedFormats formats_ = {};
  uint32_t clock_domain_ = fuchsia::hardware::audio::CLOCK_DOMAIN_MONOTONIC;
  size_t ring_buffer_size_;
  zx::vmo ring_buffer_;

  uint32_t fifo_depth_ = 0;
  zx::duration external_delay_{zx::nsec(0)};
  bool plugged_ = true;

  std::optional<fuchsia::hardware::audio::PcmFormat> selected_format_;

  bool is_running_ = false;
  zx::time mono_start_time_{0};

  async_dispatcher_t* dispatcher_;
  fidl::Binding<fuchsia::hardware::audio::StreamConfig> stream_binding_;
  std::optional<fidl::Binding<fuchsia::hardware::audio::RingBuffer>> ring_buffer_binding_;
  fidl::InterfaceRequest<fuchsia::hardware::audio::StreamConfig> stream_req_;
  fidl::InterfaceRequest<fuchsia::hardware::audio::RingBuffer> ring_buffer_req_;

  bool position_notification_values_are_set_ = false;
  zx::time position_notify_timestamp_mono_;
  uint32_t position_notify_position_bytes_ = 0;

  std::optional<fuchsia::hardware::audio::RingBuffer::WatchClockRecoveryPositionInfoCallback>
      position_notify_callback_;
};

}  // namespace media::audio::testing

#endif  // SRC_MEDIA_AUDIO_AUDIO_CORE_TESTING_FAKE_AUDIO_DRIVER_H_
