// 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.

#include "src/media/audio/drivers/virtual_audio/virtual_audio_device_impl.h"

#include <lib/zx/clock.h>

#include <memory>

#include <ddk/debug.h>

#include "src/media/audio/drivers/virtual_audio/virtual_audio_stream.h"

namespace virtual_audio {

class VirtualAudioStreamIn;
class VirtualAudioStreamOut;

// static methods
std::unique_ptr<VirtualAudioDeviceImpl> VirtualAudioDeviceImpl::Create(
    VirtualAudioControlImpl* owner, bool is_input) {
  return std::unique_ptr<VirtualAudioDeviceImpl>(new VirtualAudioDeviceImpl(owner, is_input));
}

// Don't initialize here or in ctor; do it all in Init() so ResetConfiguration has same effect.
VirtualAudioDeviceImpl::VirtualAudioDeviceImpl(VirtualAudioControlImpl* owner, bool is_input)
    : owner_(owner), is_input_(is_input) {
  ZX_DEBUG_ASSERT(owner_);

  Init();
}

// If we have not already destroyed our child stream, do so now.
VirtualAudioDeviceImpl::~VirtualAudioDeviceImpl() { RemoveStream(); }

// Initialize (or reset) a device's static configuration.
void VirtualAudioDeviceImpl::Init() {
  device_name_ = kDefaultDeviceName;
  mfr_name_ = kDefaultManufacturerName;
  prod_name_ = kDefaultProductName;
  memcpy(unique_id_, kDefaultUniqueId, sizeof(unique_id_));

  clock_domain_ = kDefaultClockDomain;
  clock_rate_adjustment_ = kDefaultClockRateAdjustment;

  // By default, we support one basic format range (stereo 16-bit 48kHz)
  supported_formats_.clear();
  supported_formats_.push_back(kDefaultFormatRange);

  fifo_depth_ = kDefaultFifoDepthBytes;
  external_delay_nsec_ = kDefaultExternalDelayNsec;

  min_buffer_frames_ = kDefaultMinBufferFrames;
  max_buffer_frames_ = kDefaultMaxBufferFrames;
  modulo_buffer_frames_ = kDefaultModuloBufferFrames;

  cur_gain_state_ = kDefaultGainState;

  hardwired_ = kDefaultHardwired;
  async_plug_notify_ = kDefaultPlugCanNotify;
  plugged_ = kDefaultPlugged;

  // The time this Configuration was created / reset.
  plug_time_ = zx::clock::get_monotonic().get();

  override_notification_frequency_ = false;
  notifications_per_ring_ = 0;
}

// Receive and cache a virtualaudio::Input binding, forwarded from the virtual_audio_service.
// ControlImpl has already associated us with the binding: when it closes we will auto-destruct.
void VirtualAudioDeviceImpl::SetBinding(
    fidl::Binding<fuchsia::virtualaudio::Input,
                  std::unique_ptr<virtual_audio::VirtualAudioDeviceImpl>>* binding) {
  ZX_ASSERT(is_input_);
  ZX_DEBUG_ASSERT(output_binding_ == nullptr);

  input_binding_ = binding;
  ZX_DEBUG_ASSERT(input_binding_->is_bound());
}

// Receive and cache a virtualaudio::Output binding, forwarded from the virtual_audio_service.
// ControlImpl has already associated us with the binding: when it closes we will auto-destruct.
void VirtualAudioDeviceImpl::SetBinding(
    fidl::Binding<fuchsia::virtualaudio::Output,
                  std::unique_ptr<virtual_audio::VirtualAudioDeviceImpl>>* binding) {
  ZX_ASSERT(!is_input_);
  ZX_DEBUG_ASSERT(input_binding_ == nullptr);

  output_binding_ = binding;
  ZX_DEBUG_ASSERT(output_binding_->is_bound());
}

// In response to an Input::Add or Output::Add call, create the stream (activate the device).
bool VirtualAudioDeviceImpl::CreateStream(zx_device_t* devnode) {
  stream_ = VirtualAudioStream::CreateStream(this, devnode, is_input_);
  return (stream_ != nullptr);
}

// Remove our child stream by calling its DdkUnbind. This may already have occurred; check for null.
//
// TODO(mpuryear): This may not safely unwind in all cases: it makes some threading assumptions that
// cannot necessarily be enforced. But until fxbug.dev/33258 is addressed, the current VAD code
// appears to be safe -- all RemoveStream callers are on the devhost primary thread:
//   ~VirtualAudioDeviceImpl from DevHost removing parent,
//   ~VirtualAudioDeviceImpl from Input|Output FIDL channel disconnecting
//   fuchsia.virtualaudio.Control.Disable
//   fuchsia.virtualaudio.Input|Output.Remove
void VirtualAudioDeviceImpl::RemoveStream() {
  if (stream_ != nullptr) {
    // Clear any queued dispatcher tasks, and no longer accept new tasks.
    task_queue_->StopAndClear();

    // This bool tells the stream that Unbind originates from us (parent), so don't call us back.
    stream_->shutdown_by_parent_ = true;

    // Shutdown won't return until any in-flight calls to PostToDispatcher are quiesced.
    // Shutdown deactivates its execution domain, and all PostToDispatcher calls are
    // made from this execution domain). This guarantee is critical, because Add changes what
    // task_queue_ points to. If calls to PostToDispatcher WERE still outstanding, then it would be
    // possible that Add could be called before task_queue_->Enqueue runs, causing us to erroneously
    // run a task associated with the older stream, in the context of the new stream.
    stream_->Shutdown();
    // Request the device be unbound.
    stream_->DdkAsyncRemove();

    // Now that the stream has done its shutdown, we release our reference.
    stream_ = nullptr;
  }
  // bindings are reset in the VirtualAudioDeviceImpl dtor
}

// In most cases, stream DdkUnbind is called by us (the parent DeviceImpl), above in RemoveStream.
// In the other cases, this RemoveStream is eventually called, but we should not RE-call DdkUnbind
// at that point. To cover those other cases, this ClearStream method allows the child stream to
// signal to its parent that it has gone away. Conversely, the flag shutdown_by_parent_ provides the
// device->stream signal in the other cases (such as when RemoveStream is called during the device
// dtor), to let the stream know that it need not and should not call us.
void VirtualAudioDeviceImpl::ClearStream() {
  // Clear any queued dispatcher tasks, and no longer accept new tasks.
  task_queue_->StopAndClear();

  // Forget about this stream, but don't do more right now -- our RemoveStream will be called later.
  stream_ = nullptr;
}

// Use closure_queue to post a dispatcher task -- cancellable if stream or device is destroyed.
void VirtualAudioDeviceImpl::PostToDispatcher(fit::closure task_to_post) {
  // We know task_queue_ isn't changing which ClosureQueue it's holding as this line is running,
  // because RemoveStream always runs on the same thread as Add (the main devhost thread, the FIDL
  // dispatch thread, the ClosureQueue's destination thread), and RemoveStream quiesces all calls to
  // PostToDispatcher before it returns (and thus before Add changes what task_queue_ points to).
  task_queue_->Enqueue(std::move(task_to_post));
}

//
// virtualaudio::Configuration implementation
//
void VirtualAudioDeviceImpl::SetDeviceName(std::string device_name) {
  device_name_ = device_name;

  WarnActiveStreamNotAffected(__func__);
}

void VirtualAudioDeviceImpl::SetManufacturer(std::string manufacturer_name) {
  mfr_name_ = manufacturer_name;

  WarnActiveStreamNotAffected(__func__);
}

void VirtualAudioDeviceImpl::SetProduct(std::string product_name) {
  prod_name_ = product_name;

  WarnActiveStreamNotAffected(__func__);
}

void VirtualAudioDeviceImpl::SetUniqueId(std::array<uint8_t, 16> unique_id) {
  memcpy(unique_id_, unique_id.data(), sizeof(unique_id_));

  WarnActiveStreamNotAffected(__func__);
}

// After creation or reset, one default format range is always available.
void VirtualAudioDeviceImpl::AddFormatRange(uint32_t format_flags, uint32_t min_rate,
                                            uint32_t max_rate, uint8_t min_chans, uint8_t max_chans,
                                            uint16_t rate_family_flags) {
  audio_stream_format_range_t range = {.sample_formats = format_flags,
                                       .min_frames_per_second = min_rate,
                                       .max_frames_per_second = max_rate,
                                       .min_channels = min_chans,
                                       .max_channels = max_chans,
                                       .flags = rate_family_flags};

  supported_formats_.push_back(range);

  WarnActiveStreamNotAffected(__func__);
}

void VirtualAudioDeviceImpl::ClearFormatRanges() {
  supported_formats_.clear();
  WarnActiveStreamNotAffected(__func__);
}

void VirtualAudioDeviceImpl::WarnActiveStreamNotAffected(const char* func_name) {
  if (stream_ != nullptr) {
    zxlogf(WARNING, "%s updates the static config, but has no effect on existing streams",
           func_name);
  }
}

void VirtualAudioDeviceImpl::SetClockProperties(int32_t clock_domain,
                                                int32_t initial_rate_adjustment_ppm) {
  clock_domain_ = clock_domain;
  clock_rate_adjustment_ = initial_rate_adjustment_ppm;

  WarnActiveStreamNotAffected(__func__);
}

void VirtualAudioDeviceImpl::SetFifoDepth(uint32_t fifo_depth_bytes) {
  fifo_depth_ = fifo_depth_bytes;

  WarnActiveStreamNotAffected(__func__);
}

void VirtualAudioDeviceImpl::SetExternalDelay(zx_duration_t external_delay) {
  external_delay_nsec_ = external_delay;

  WarnActiveStreamNotAffected(__func__);
}

void VirtualAudioDeviceImpl::SetRingBufferRestrictions(uint32_t min_frames, uint32_t max_frames,
                                                       uint32_t modulo_frames) {
  ZX_DEBUG_ASSERT(min_frames <= max_frames);
  ZX_DEBUG_ASSERT(min_frames % modulo_frames == 0);
  ZX_DEBUG_ASSERT(max_frames % modulo_frames == 0);

  min_buffer_frames_ = min_frames;
  max_buffer_frames_ = max_frames;
  modulo_buffer_frames_ = modulo_frames;

  WarnActiveStreamNotAffected(__func__);
}

void VirtualAudioDeviceImpl::SetGainProperties(float min_gain_db, float max_gain_db,
                                               float gain_step_db, float current_gain_db,
                                               bool can_mute, bool current_mute, bool can_agc,
                                               bool current_agc) {
  cur_gain_state_ = {.cur_mute = current_mute,
                     .cur_agc = current_agc,
                     .cur_gain = current_gain_db,

                     .can_mute = can_mute,
                     .can_agc = can_agc,

                     .min_gain = min_gain_db,
                     .max_gain = max_gain_db,
                     .gain_step = gain_step_db};

  WarnActiveStreamNotAffected(__func__);
}

void VirtualAudioDeviceImpl::SetPlugProperties(zx_time_t plug_change_time, bool plugged,
                                               bool hardwired, bool can_notify) {
  plug_time_ = plug_change_time;

  plugged_ = plugged;
  hardwired_ = hardwired;
  async_plug_notify_ = can_notify;

  WarnActiveStreamNotAffected(__func__);
}

void VirtualAudioDeviceImpl::ResetConfiguration() {
  Init();

  WarnActiveStreamNotAffected(__func__);
}

//
// virtualaudio::Device implementation
//
// Create a virtual audio device using the currently-specified configuration.
void VirtualAudioDeviceImpl::Add() {
  if (!owner_->enabled()) {
    zxlogf(WARNING, "%s: Disabled, cannot add stream", __func__);
    return;
  }

  if (stream_ != nullptr) {
    zxlogf(WARNING, "%s: %p already has stream %p", __func__, this, stream_.get());
    return;
  }

  // This ClosureQueue is created when stream is created), deactivated (via StopAndClear) when
  // stream is removed, and synchronized by being on devhost dispatcher thread (our FIDL thread).
  // DeviceImpl and Stream both call PostToDispatcher, and all are quiesced before we get here.
  // DeviceImpl makes those calls on the FIDL thread (task_queue_'s destination thread); all are
  // enqueued and subsequently discarded (via StopAndClear) upon RemoveStream. Stream makes those
  // calls in its execution domain, which is synchronously deactivated during its DdkUnbind.
  task_queue_.emplace(owner_->dispatcher(), thrd_current());
  if (!CreateStream(owner_->dev_node())) {
    zxlogf(ERROR, "CreateStream failed");
    task_queue_->StopAndClear();
    return;
  }
}

// Remove the associated virtual audio device.
void VirtualAudioDeviceImpl::Remove() {
  if (!owner_->enabled()) {
    zxlogf(WARNING, "%s: Disabled, no streams for removal", __func__);
    ZX_DEBUG_ASSERT(stream_ == nullptr);
    return;
  }

  if (stream_ == nullptr) {
    zxlogf(WARNING, "%s: %p has no stream to remove", __func__, this);
    return;
  }

  // If stream_ exists, null our copy and call SimpleAudioStream::DdkUnbind (which eventually calls
  // ShutdownHook and re-nulls). We need this because stream terminations come either from "device"
  // (direct DdkUnbind call), or from "parent" (Control::Disable, Device::Remove, ~DeviceImpl).
  RemoveStream();
}

void VirtualAudioDeviceImpl::GetFormat(
    fuchsia::virtualaudio::Device::GetFormatCallback format_callback) {
  if (stream_ == nullptr) {
    zxlogf(WARNING, "%s: %p has no stream for this request", __func__, this);
    return;
  }

  stream_->EnqueueFormatRequest(std::move(format_callback));
}

// Deliver SetFormat notification on binding's thread, if binding is valid.
void VirtualAudioDeviceImpl::NotifySetFormat(uint32_t frames_per_second, uint32_t sample_format,
                                             uint32_t num_channels, zx_duration_t external_delay) {
  PostToDispatcher([this, frames_per_second, sample_format, num_channels, external_delay]() {
    if (input_binding_ && input_binding_->is_bound()) {
      input_binding_->events().OnSetFormat(frames_per_second, sample_format, num_channels,
                                           external_delay);
    } else if (output_binding_ && output_binding_->is_bound()) {
      output_binding_->events().OnSetFormat(frames_per_second, sample_format, num_channels,
                                            external_delay);
    }
  });
}

void VirtualAudioDeviceImpl::GetGain(fuchsia::virtualaudio::Device::GetGainCallback gain_callback) {
  if (stream_ == nullptr) {
    zxlogf(WARNING, "%s: %p has no stream for this request", __func__, this);
    return;
  }

  stream_->EnqueueGainRequest(std::move(gain_callback));
}

// Deliver SetGain notification on binding's thread, if binding is valid.
void VirtualAudioDeviceImpl::NotifySetGain(bool current_mute, bool current_agc,
                                           float current_gain_db) {
  PostToDispatcher([this, current_mute, current_agc, current_gain_db]() {
    if (input_binding_ && input_binding_->is_bound()) {
      input_binding_->events().OnSetGain(current_mute, current_agc, current_gain_db);
    } else if (output_binding_ && output_binding_->is_bound()) {
      output_binding_->events().OnSetGain(current_mute, current_agc, current_gain_db);
    }
  });
}

void VirtualAudioDeviceImpl::GetBuffer(
    fuchsia::virtualaudio::Device::GetBufferCallback buffer_callback) {
  if (stream_ == nullptr) {
    zxlogf(WARNING, "%s: %p has no stream for this request", __func__, this);
    return;
  }

  stream_->EnqueueBufferRequest(std::move(buffer_callback));
}

// Deliver SetBuffer notification on binding's thread, if binding is valid.
void VirtualAudioDeviceImpl::NotifyBufferCreated(zx::vmo ring_buffer_vmo,
                                                 uint32_t num_ring_buffer_frames,
                                                 uint32_t notifications_per_ring) {
  PostToDispatcher([this, ring_buffer_vmo = std::move(ring_buffer_vmo), num_ring_buffer_frames,
                    notifications_per_ring]() mutable {
    if (input_binding_ && input_binding_->is_bound()) {
      input_binding_->events().OnBufferCreated(std::move(ring_buffer_vmo), num_ring_buffer_frames,
                                               notifications_per_ring);
    } else if (output_binding_ && output_binding_->is_bound()) {
      output_binding_->events().OnBufferCreated(std::move(ring_buffer_vmo), num_ring_buffer_frames,
                                                notifications_per_ring);
    }
  });
}

// Override AudioCore's systemwide position notification cadence, in favor of a per-stream
// notification cadence. Update the static config, and if active, tell device to dynamically change.
void VirtualAudioDeviceImpl::SetNotificationFrequency(uint32_t notifications_per_ring) {
  // This is a DeviceImpl property (stream has a property with same name)
  override_notification_frequency_ = true;
  notifications_per_ring_ = notifications_per_ring;

  if (stream_ != nullptr) {
    stream_->EnqueueNotificationOverride(notifications_per_ring);
  }
}

// Deliver Start notification on binding's thread, if binding is valid.
void VirtualAudioDeviceImpl::NotifyStart(zx_time_t start_time) {
  PostToDispatcher([this, start_time]() {
    if (is_input_) {
      ZX_ASSERT(input_binding_ && input_binding_->is_bound());
      input_binding_->events().OnStart(start_time);
    } else {
      ZX_ASSERT(output_binding_ && output_binding_->is_bound());
      output_binding_->events().OnStart(start_time);
    }
  });
}

// Deliver Stop notification on binding's thread, if binding is valid.
void VirtualAudioDeviceImpl::NotifyStop(zx_time_t stop_time, uint32_t ring_buffer_position) {
  PostToDispatcher([this, stop_time, ring_buffer_position]() {
    if (is_input_) {
      ZX_ASSERT(input_binding_ && input_binding_->is_bound());
      input_binding_->events().OnStop(stop_time, ring_buffer_position);
    } else {
      ZX_ASSERT(output_binding_ && output_binding_->is_bound());
      output_binding_->events().OnStop(stop_time, ring_buffer_position);
    }
  });
}

void VirtualAudioDeviceImpl::GetPosition(
    fuchsia::virtualaudio::Device::GetPositionCallback position_callback) {
  if (stream_ == nullptr) {
    zxlogf(WARNING, "%s: %p has no stream for this request", __func__, this);
    return;
  }

  stream_->EnqueuePositionRequest(std::move(position_callback));
}

// Deliver Position notification on binding's thread, if binding is valid.
void VirtualAudioDeviceImpl::NotifyPosition(zx_time_t monotonic_time,
                                            uint32_t ring_buffer_position) {
  PostToDispatcher([this, monotonic_time, ring_buffer_position]() {
    if (is_input_) {
      ZX_ASSERT(input_binding_ && input_binding_->is_bound());
      input_binding_->events().OnPositionNotify(monotonic_time, ring_buffer_position);
    } else {
      ZX_ASSERT(output_binding_ && output_binding_->is_bound());
      output_binding_->events().OnPositionNotify(monotonic_time, ring_buffer_position);
    }
  });
}

// Change the plug state on-the-fly for this active virtual audio device.
void VirtualAudioDeviceImpl::ChangePlugState(zx_time_t plug_change_time, bool plugged) {
  // Update static config, and tell (if present) stream to dynamically change.
  plug_time_ = plug_change_time;
  plugged_ = plugged;

  if (!owner_->enabled()) {
    zxlogf(WARNING, "%s: Disabled, cannot change plug state; changing only the static config",
           __func__);
    return;
  }

  if (stream_ == nullptr) {
    zxlogf(WARNING, "%s: %p has no stream; cannot change dynamic plug state", __func__, this);
    return;
  }

  stream_->EnqueuePlugChange(plugged);
}

// Change the plug state on-the-fly for this active virtual audio device.
void VirtualAudioDeviceImpl::AdjustClockRate(int32_t ppm_from_monotonic) {
  // Update static config, and tell (if present) stream to dynamically change.
  clock_rate_adjustment_ = ppm_from_monotonic;

  if (!owner_->enabled()) {
    zxlogf(WARNING, "%s: Disabled, cannot adjust clock rate; changing only the static config",
           __func__);
    return;
  }

  if (stream_ == nullptr) {
    zxlogf(WARNING, "%s: %p has no stream; cannot change clock rate", __func__, this);
    return;
  }

  stream_->EnqueueClockRateAdjustment(ppm_from_monotonic);
}

}  // namespace virtual_audio
