// Copyright 2020 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/audio_core/audio_capturer.h"

#include <lib/fit/defer.h>

#include "src/media/audio/audio_core/audio_admin.h"
#include "src/media/audio/audio_core/reporter.h"
#include "src/media/audio/audio_core/stream_usage.h"
#include "src/media/audio/lib/clock/clone_mono.h"
#include "src/media/audio/lib/clock/utils.h"
#include "src/media/audio/lib/logging/logging.h"

namespace media::audio {
namespace {

constexpr float kInitialCaptureGainDb = Gain::kUnityGainDb;

}

AudioCapturer::AudioCapturer(fuchsia::media::AudioCapturerConfiguration configuration,
                             std::optional<Format> format,
                             fidl::InterfaceRequest<fuchsia::media::AudioCapturer> request,
                             Context* context)
    : BaseCapturer(std::move(format), std::move(request), context),
      loopback_(configuration.is_loopback()),
      mute_(false),
      stream_gain_db_(kInitialCaptureGainDb) {
  FX_DCHECK(context);
  if (!loopback_) {
    context->volume_manager().AddStream(this);
    if (configuration.input().has_usage()) {
      usage_ = configuration.input().usage();
    }
  }
  reporter().SetUsage(CaptureUsageFromFidlCaptureUsage(usage_));
}

AudioCapturer::~AudioCapturer() {
  if (!loopback_) {
    context().volume_manager().RemoveStream(this);
  }
}

void AudioCapturer::ReportStart() {
  BaseCapturer::ReportStart();
  if (!loopback_) {
    context().audio_admin().UpdateCapturerState(usage_, true, this);
  }
}

void AudioCapturer::ReportStop() {
  BaseCapturer::ReportStop();
  if (!loopback_) {
    context().audio_admin().UpdateCapturerState(usage_, false, this);
  }
}

void AudioCapturer::OnStateChanged(State old_state, State new_state) {
  BaseCapturer::OnStateChanged(old_state, new_state);
  if (!loopback_ && new_state == State::OperatingSync) {
    context().volume_manager().NotifyStreamChanged(this);
  }
}

void AudioCapturer::SetRoutingProfile(bool routable) {
  auto profile =
      RoutingProfile{.routable = routable, .usage = StreamUsage::WithCaptureUsage(capture_usage())};
  context().route_graph().SetCapturerRoutingProfile(*this, std::move(profile));

  // Once we route the capturer, we accept the default reference clock if one hasn't yet been set.
  if (routable) {
    reference_clock_is_set_ = true;
  }
}

void AudioCapturer::OnLinkAdded() {
  BaseCapturer::OnLinkAdded();
  if (!loopback_) {
    context().volume_manager().NotifyStreamChanged(this);
  }
}

constexpr auto kRequiredClockRights = ZX_RIGHT_DUPLICATE | ZX_RIGHT_TRANSFER | ZX_RIGHT_READ;
// If received clock is null, use our adjustable clock. Else, use this new clock. Fail/disconnect,
// if the client-submitted clock has insufficient rights. Strip off other rights such as WRITE.
void AudioCapturer::SetReferenceClock(zx::clock raw_clock) {
  TRACE_DURATION("audio", "AudioCapturer::SetReferenceClock");
  AUDIO_LOG_OBJ(DEBUG, this);

  auto cleanup = fit::defer([this]() { BeginShutdown(); });

  // We cannot change the reference clock, once set. Also, once the capturer is routed to a device
  // (which occurs upon AddPayloadBuffer), we set the default clock if one has not yet been set.
  if (reference_clock_is_set_) {
    FX_LOGS(WARNING) << "Cannot change reference clock once it is set!";
    return;
  }

  zx_status_t status;
  if (raw_clock.is_valid()) {
    // If raw_clock doesn't have DUPLICATE or READ or TRANSFER rights, return (i.e. shutdown).
    status = raw_clock.replace(kRequiredClockRights, &raw_clock);
    if (status != ZX_OK) {
      FX_PLOGS(WARNING, status) << "Could not set rights on client-submitted reference clock";
      return;
    }
    SetClock(AudioClock::ClientFixed(std::move(raw_clock)));
  } else {
    // To achieve "no-SRC", we will rate-adjust this clock to match the device clock.
    SetClock(AudioClock::ClientAdjustable(audio::clock::AdjustableCloneOfMonotonic()));
  }

  reference_clock_is_set_ = true;

  cleanup.cancel();
}

void AudioCapturer::SetPcmStreamType(fuchsia::media::AudioStreamType stream_type) {
  TRACE_DURATION("audio", "AudioCapturer::SetPcmStreamType");
  // If something goes wrong, hang up the phone and shutdown.
  auto cleanup = fit::defer([this]() { BeginShutdown(); });

  // If our shared buffer has been assigned, we are operating and our mode can no longer be changed.
  State state = capture_state();
  if (state != State::WaitingForVmo) {
    FX_LOGS(WARNING) << "Cannot change format after payload buffer has been added"
                     << "(state = " << static_cast<uint32_t>(state) << ")";
    return;
  }

  auto format_result = Format::Create(stream_type);
  if (format_result.is_error()) {
    FX_LOGS(WARNING) << "AudioCapturer: PcmStreamType is invalid";
    return;
  }

  // Success, record our new format.
  UpdateFormat(format_result.take_value());

  cleanup.cancel();
}

void AudioCapturer::BindGainControl(
    fidl::InterfaceRequest<fuchsia::media::audio::GainControl> request) {
  TRACE_DURATION("audio", "AudioCapturer::BindGainControl");
  gain_control_bindings_.AddBinding(this, std::move(request));
}

void AudioCapturer::SetUsage(fuchsia::media::AudioCaptureUsage usage) {
  TRACE_DURATION("audio", "AudioCapturer::SetUsage");
  if (usage == usage_) {
    return;
  }
  if (loopback_) {
    FX_LOGS(WARNING) << "SetUsage on loopback capturer is not allowed";
    return;
  }

  ReportStop();
  reporter().SetUsage(CaptureUsageFromFidlCaptureUsage(usage));
  usage_ = usage;
  context().volume_manager().NotifyStreamChanged(this);
  State state = capture_state();
  SetRoutingProfile(StateIsRoutable(state));
  if (state == State::OperatingAsync) {
    ReportStart();
  }
  if (state == State::OperatingSync) {
    if (has_pending_packets()) {
      ReportStart();
    }
  }
}

bool AudioCapturer::GetStreamMute() const { return mute_; }

fuchsia::media::Usage AudioCapturer::GetStreamUsage() const {
  // We should only be calling these from the StreamVolumeManager. We don't register LOOPBACK
  // capturers with the StreamVolumeManager since those capturers do not have a compatible
  // usage.
  FX_DCHECK(!loopback_);
  fuchsia::media::Usage usage;
  usage.set_capture_usage(usage_);
  return usage;
}

void AudioCapturer::RealizeVolume(VolumeCommand volume_command) {
  if (volume_command.ramp.has_value()) {
    FX_LOGS(WARNING) << "Capturer gain ramping is not implemented";
  }

  context().link_matrix().ForEachSourceLink(
      *this, [this, volume_command](LinkMatrix::LinkHandle link) {
        float gain_db = link.loudness_transform->Evaluate<3>({
            VolumeValue{volume_command.volume},
            GainDbFsValue{volume_command.gain_db_adjustment},
            GainDbFsValue{stream_gain_db_.load()},
        });
        // TODO(fxbug.dev/51049) Logging should be removed upon creation of inspect tool or other
        // real-time method for gain observation
        if (gain_db != 0.0) {
          FX_LOGS(INFO) << this << " " << StreamUsage::WithCaptureUsage(usage_).ToString()
                        << " Gain(" << gain_db << "db) = "
                        << "Vol(" << volume_command.volume << ") + GainAdjustment("
                        << volume_command.gain_db_adjustment << "db) + StreamGain("
                        << stream_gain_db_ << "db)";
        }

        mix_domain().PostTask(
            [link, gain_db]() { link.mixer->bookkeeping().gain.SetDestGain(gain_db); });
      });
}

void AudioCapturer::SetGain(float gain_db) {
  TRACE_DURATION("audio", "AudioCapturer::SetGain");
  // Before setting stream_gain_db_, we should always perform this range check.
  if ((gain_db < fuchsia::media::audio::MUTED_GAIN_DB) ||
      (gain_db > fuchsia::media::audio::MAX_GAIN_DB) || isnan(gain_db)) {
    FX_LOGS(WARNING) << "SetGain(" << gain_db << " dB) out of range.";
    BeginShutdown();
    return;
  }

  // If the incoming SetGain request represents no change, we're done
  // (once we add gain ramping, this type of check isn't workable).
  if (stream_gain_db_ == gain_db) {
    return;
  }

  reporter().SetGain(gain_db);

  stream_gain_db_.store(gain_db);
  if (!loopback_) {
    context().volume_manager().NotifyStreamChanged(this);
  }

  NotifyGainMuteChanged();
}

void AudioCapturer::SetMute(bool mute) {
  TRACE_DURATION("audio", "AudioCapturer::SetMute");
  // If the incoming SetMute request represents no change, we're done.
  if (mute_ == mute) {
    return;
  }

  reporter().SetMute(mute);

  mute_ = mute;

  if (!loopback_) {
    context().volume_manager().NotifyStreamChanged(this);
  }
  NotifyGainMuteChanged();
}

void AudioCapturer::NotifyGainMuteChanged() {
  TRACE_DURATION("audio", "AudioCapturer::NotifyGainMuteChanged");
  // Consider making these events disable-able like MinLeadTime.
  for (auto& gain_binding : gain_control_bindings_.bindings()) {
    gain_binding->events().OnGainMuteChanged(stream_gain_db_, mute_);
  }
}

}  // namespace media::audio
