/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_device/android/aaudio_wrapper.h"

#include "modules/audio_device/android/audio_manager.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/time_utils.h"

#define LOG_ON_ERROR(op)                                                      \
  do {                                                                        \
    aaudio_result_t result = (op);                                            \
    if (result != AAUDIO_OK) {                                                \
      RTC_LOG(LS_ERROR) << #op << ": " << AAudio_convertResultToText(result); \
    }                                                                         \
  } while (0)

#define RETURN_ON_ERROR(op, ...)                                              \
  do {                                                                        \
    aaudio_result_t result = (op);                                            \
    if (result != AAUDIO_OK) {                                                \
      RTC_LOG(LS_ERROR) << #op << ": " << AAudio_convertResultToText(result); \
      return __VA_ARGS__;                                                     \
    }                                                                         \
  } while (0)

namespace webrtc {

namespace {

const char* DirectionToString(aaudio_direction_t direction) {
  switch (direction) {
    case AAUDIO_DIRECTION_OUTPUT:
      return "OUTPUT";
    case AAUDIO_DIRECTION_INPUT:
      return "INPUT";
    default:
      return "UNKNOWN";
  }
}

const char* SharingModeToString(aaudio_sharing_mode_t mode) {
  switch (mode) {
    case AAUDIO_SHARING_MODE_EXCLUSIVE:
      return "EXCLUSIVE";
    case AAUDIO_SHARING_MODE_SHARED:
      return "SHARED";
    default:
      return "UNKNOWN";
  }
}

const char* PerformanceModeToString(aaudio_performance_mode_t mode) {
  switch (mode) {
    case AAUDIO_PERFORMANCE_MODE_NONE:
      return "NONE";
    case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
      return "POWER_SAVING";
    case AAUDIO_PERFORMANCE_MODE_LOW_LATENCY:
      return "LOW_LATENCY";
    default:
      return "UNKNOWN";
  }
}

const char* FormatToString(int32_t id) {
  switch (id) {
    case AAUDIO_FORMAT_INVALID:
      return "INVALID";
    case AAUDIO_FORMAT_UNSPECIFIED:
      return "UNSPECIFIED";
    case AAUDIO_FORMAT_PCM_I16:
      return "PCM_I16";
    case AAUDIO_FORMAT_PCM_FLOAT:
      return "FLOAT";
    default:
      return "UNKNOWN";
  }
}

void ErrorCallback(AAudioStream* stream,
                   void* user_data,
                   aaudio_result_t error) {
  RTC_DCHECK(user_data);
  AAudioWrapper* aaudio_wrapper = reinterpret_cast<AAudioWrapper*>(user_data);
  RTC_LOG(WARNING) << "ErrorCallback: "
                   << DirectionToString(aaudio_wrapper->direction());
  RTC_DCHECK(aaudio_wrapper->observer());
  aaudio_wrapper->observer()->OnErrorCallback(error);
}

aaudio_data_callback_result_t DataCallback(AAudioStream* stream,
                                           void* user_data,
                                           void* audio_data,
                                           int32_t num_frames) {
  RTC_DCHECK(user_data);
  RTC_DCHECK(audio_data);
  AAudioWrapper* aaudio_wrapper = reinterpret_cast<AAudioWrapper*>(user_data);
  RTC_DCHECK(aaudio_wrapper->observer());
  return aaudio_wrapper->observer()->OnDataCallback(audio_data, num_frames);
}

// Wraps the stream builder object to ensure that it is released properly when
// the stream builder goes out of scope.
class ScopedStreamBuilder {
 public:
  ScopedStreamBuilder() {
    LOG_ON_ERROR(AAudio_createStreamBuilder(&builder_));
    RTC_DCHECK(builder_);
  }
  ~ScopedStreamBuilder() {
    if (builder_) {
      LOG_ON_ERROR(AAudioStreamBuilder_delete(builder_));
    }
  }

  AAudioStreamBuilder* get() const { return builder_; }

 private:
  AAudioStreamBuilder* builder_ = nullptr;
};

}  // namespace

AAudioWrapper::AAudioWrapper(AudioManager* audio_manager,
                             aaudio_direction_t direction,
                             AAudioObserverInterface* observer)
    : direction_(direction), observer_(observer) {
  RTC_LOG(INFO) << "ctor";
  RTC_DCHECK(observer_);
  direction_ == AAUDIO_DIRECTION_OUTPUT
      ? audio_parameters_ = audio_manager->GetPlayoutAudioParameters()
      : audio_parameters_ = audio_manager->GetRecordAudioParameters();
  aaudio_thread_checker_.DetachFromThread();
  RTC_LOG(INFO) << audio_parameters_.ToString();
}

AAudioWrapper::~AAudioWrapper() {
  RTC_LOG(INFO) << "dtor";
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_DCHECK(!stream_);
}

bool AAudioWrapper::Init() {
  RTC_LOG(INFO) << "Init";
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  // Creates a stream builder which can be used to open an audio stream.
  ScopedStreamBuilder builder;
  // Configures the stream builder using audio parameters given at construction.
  SetStreamConfiguration(builder.get());
  // Opens a stream based on options in the stream builder.
  if (!OpenStream(builder.get())) {
    return false;
  }
  // Ensures that the opened stream could activate the requested settings.
  if (!VerifyStreamConfiguration()) {
    return false;
  }
  // Optimizes the buffer scheme for lowest possible latency and creates
  // additional buffer logic to match the 10ms buffer size used in WebRTC.
  if (!OptimizeBuffers()) {
    return false;
  }
  LogStreamState();
  return true;
}

bool AAudioWrapper::Start() {
  RTC_LOG(INFO) << "Start";
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  // TODO(henrika): this state check might not be needed.
  aaudio_stream_state_t current_state = AAudioStream_getState(stream_);
  if (current_state != AAUDIO_STREAM_STATE_OPEN) {
    RTC_LOG(LS_ERROR) << "Invalid state: "
                      << AAudio_convertStreamStateToText(current_state);
    return false;
  }
  // Asynchronous request for the stream to start.
  RETURN_ON_ERROR(AAudioStream_requestStart(stream_), false);
  LogStreamState();
  return true;
}

bool AAudioWrapper::Stop() {
  RTC_LOG(INFO) << "Stop: " << DirectionToString(direction());
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  // Asynchronous request for the stream to stop.
  RETURN_ON_ERROR(AAudioStream_requestStop(stream_), false);
  CloseStream();
  aaudio_thread_checker_.DetachFromThread();
  return true;
}

double AAudioWrapper::EstimateLatencyMillis() const {
  RTC_DCHECK(stream_);
  double latency_millis = 0.0;
  if (direction() == AAUDIO_DIRECTION_INPUT) {
    // For input streams. Best guess we can do is to use the current burst size
    // as delay estimate.
    latency_millis = static_cast<double>(frames_per_burst()) / sample_rate() *
                     rtc::kNumMillisecsPerSec;
  } else {
    int64_t existing_frame_index;
    int64_t existing_frame_presentation_time;
    // Get the time at which a particular frame was presented to audio hardware.
    aaudio_result_t result = AAudioStream_getTimestamp(
        stream_, CLOCK_MONOTONIC, &existing_frame_index,
        &existing_frame_presentation_time);
    // Results are only valid when the stream is in AAUDIO_STREAM_STATE_STARTED.
    if (result == AAUDIO_OK) {
      // Get write index for next audio frame.
      int64_t next_frame_index = frames_written();
      // Number of frames between next frame and the existing frame.
      int64_t frame_index_delta = next_frame_index - existing_frame_index;
      // Assume the next frame will be written now.
      int64_t next_frame_write_time = rtc::TimeNanos();
      // Calculate time when next frame will be presented to the hardware taking
      // sample rate into account.
      int64_t frame_time_delta =
          (frame_index_delta * rtc::kNumNanosecsPerSec) / sample_rate();
      int64_t next_frame_presentation_time =
          existing_frame_presentation_time + frame_time_delta;
      // Derive a latency estimate given results above.
      latency_millis = static_cast<double>(next_frame_presentation_time -
                                           next_frame_write_time) /
                       rtc::kNumNanosecsPerMillisec;
    }
  }
  return latency_millis;
}

// Returns new buffer size or a negative error value if buffer size could not
// be increased.
bool AAudioWrapper::IncreaseOutputBufferSize() {
  RTC_LOG(INFO) << "IncreaseBufferSize";
  RTC_DCHECK(stream_);
  RTC_DCHECK(aaudio_thread_checker_.CalledOnValidThread());
  RTC_DCHECK_EQ(direction(), AAUDIO_DIRECTION_OUTPUT);
  aaudio_result_t buffer_size = AAudioStream_getBufferSizeInFrames(stream_);
  // Try to increase size of buffer with one burst to reduce risk of underrun.
  buffer_size += frames_per_burst();
  // Verify that the new buffer size is not larger than max capacity.
  // TODO(henrika): keep track of case when we reach the capacity limit.
  const int32_t max_buffer_size = buffer_capacity_in_frames();
  if (buffer_size > max_buffer_size) {
    RTC_LOG(LS_ERROR) << "Required buffer size (" << buffer_size
                      << ") is higher than max: " << max_buffer_size;
    return false;
  }
  RTC_LOG(INFO) << "Updating buffer size to: " << buffer_size
                << " (max=" << max_buffer_size << ")";
  buffer_size = AAudioStream_setBufferSizeInFrames(stream_, buffer_size);
  if (buffer_size < 0) {
    RTC_LOG(LS_ERROR) << "Failed to change buffer size: "
                      << AAudio_convertResultToText(buffer_size);
    return false;
  }
  RTC_LOG(INFO) << "Buffer size changed to: " << buffer_size;
  return true;
}

void AAudioWrapper::ClearInputStream(void* audio_data, int32_t num_frames) {
  RTC_LOG(INFO) << "ClearInputStream";
  RTC_DCHECK(stream_);
  RTC_DCHECK(aaudio_thread_checker_.CalledOnValidThread());
  RTC_DCHECK_EQ(direction(), AAUDIO_DIRECTION_INPUT);
  aaudio_result_t cleared_frames = 0;
  do {
    cleared_frames = AAudioStream_read(stream_, audio_data, num_frames, 0);
  } while (cleared_frames > 0);
}

AAudioObserverInterface* AAudioWrapper::observer() const {
  return observer_;
}

AudioParameters AAudioWrapper::audio_parameters() const {
  return audio_parameters_;
}

int32_t AAudioWrapper::samples_per_frame() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getSamplesPerFrame(stream_);
}

int32_t AAudioWrapper::buffer_size_in_frames() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getBufferSizeInFrames(stream_);
}

int32_t AAudioWrapper::buffer_capacity_in_frames() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getBufferCapacityInFrames(stream_);
}

int32_t AAudioWrapper::device_id() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getDeviceId(stream_);
}

int32_t AAudioWrapper::xrun_count() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getXRunCount(stream_);
}

int32_t AAudioWrapper::format() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getFormat(stream_);
}

int32_t AAudioWrapper::sample_rate() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getSampleRate(stream_);
}

int32_t AAudioWrapper::channel_count() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getChannelCount(stream_);
}

int32_t AAudioWrapper::frames_per_callback() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getFramesPerDataCallback(stream_);
}

aaudio_sharing_mode_t AAudioWrapper::sharing_mode() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getSharingMode(stream_);
}

aaudio_performance_mode_t AAudioWrapper::performance_mode() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getPerformanceMode(stream_);
}

aaudio_stream_state_t AAudioWrapper::stream_state() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getState(stream_);
}

int64_t AAudioWrapper::frames_written() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getFramesWritten(stream_);
}

int64_t AAudioWrapper::frames_read() const {
  RTC_DCHECK(stream_);
  return AAudioStream_getFramesRead(stream_);
}

void AAudioWrapper::SetStreamConfiguration(AAudioStreamBuilder* builder) {
  RTC_LOG(INFO) << "SetStreamConfiguration";
  RTC_DCHECK(builder);
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  // Request usage of default primary output/input device.
  // TODO(henrika): verify that default device follows Java APIs.
  // https://developer.android.com/reference/android/media/AudioDeviceInfo.html.
  AAudioStreamBuilder_setDeviceId(builder, AAUDIO_UNSPECIFIED);
  // Use preferred sample rate given by the audio parameters.
  AAudioStreamBuilder_setSampleRate(builder, audio_parameters().sample_rate());
  // Use preferred channel configuration given by the audio parameters.
  AAudioStreamBuilder_setChannelCount(builder, audio_parameters().channels());
  // Always use 16-bit PCM audio sample format.
  AAudioStreamBuilder_setFormat(builder, AAUDIO_FORMAT_PCM_I16);
  // TODO(henrika): investigate effect of using AAUDIO_SHARING_MODE_EXCLUSIVE.
  // Ask for exclusive mode since this will give us the lowest possible latency.
  // If exclusive mode isn't available, shared mode will be used instead.
  AAudioStreamBuilder_setSharingMode(builder, AAUDIO_SHARING_MODE_SHARED);
  // Use the direction that was given at construction.
  AAudioStreamBuilder_setDirection(builder, direction_);
  // TODO(henrika): investigate performance using different performance modes.
  AAudioStreamBuilder_setPerformanceMode(builder,
                                         AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
  // Given that WebRTC applications require low latency, our audio stream uses
  // an asynchronous callback function to transfer data to and from the
  // application. AAudio executes the callback in a higher-priority thread that
  // has better performance.
  AAudioStreamBuilder_setDataCallback(builder, DataCallback, this);
  // Request that AAudio calls this functions if any error occurs on a callback
  // thread.
  AAudioStreamBuilder_setErrorCallback(builder, ErrorCallback, this);
}

bool AAudioWrapper::OpenStream(AAudioStreamBuilder* builder) {
  RTC_LOG(INFO) << "OpenStream";
  RTC_DCHECK(builder);
  AAudioStream* stream = nullptr;
  RETURN_ON_ERROR(AAudioStreamBuilder_openStream(builder, &stream), false);
  stream_ = stream;
  LogStreamConfiguration();
  return true;
}

void AAudioWrapper::CloseStream() {
  RTC_LOG(INFO) << "CloseStream";
  RTC_DCHECK(stream_);
  LOG_ON_ERROR(AAudioStream_close(stream_));
  stream_ = nullptr;
}

void AAudioWrapper::LogStreamConfiguration() {
  RTC_DCHECK(stream_);
  char ss_buf[1024];
  rtc::SimpleStringBuilder ss(ss_buf);
  ss << "Stream Configuration: ";
  ss << "sample rate=" << sample_rate() << ", channels=" << channel_count();
  ss << ", samples per frame=" << samples_per_frame();
  ss << ", format=" << FormatToString(format());
  ss << ", sharing mode=" << SharingModeToString(sharing_mode());
  ss << ", performance mode=" << PerformanceModeToString(performance_mode());
  ss << ", direction=" << DirectionToString(direction());
  ss << ", device id=" << AAudioStream_getDeviceId(stream_);
  ss << ", frames per callback=" << frames_per_callback();
  RTC_LOG(INFO) << ss.str();
}

void AAudioWrapper::LogStreamState() {
  RTC_LOG(INFO) << "AAudio stream state: "
                << AAudio_convertStreamStateToText(stream_state());
}

bool AAudioWrapper::VerifyStreamConfiguration() {
  RTC_LOG(INFO) << "VerifyStreamConfiguration";
  RTC_DCHECK(stream_);
  // TODO(henrika): should we verify device ID as well?
  if (AAudioStream_getSampleRate(stream_) != audio_parameters().sample_rate()) {
    RTC_LOG(LS_ERROR) << "Stream unable to use requested sample rate";
    return false;
  }
  if (AAudioStream_getChannelCount(stream_) !=
      static_cast<int32_t>(audio_parameters().channels())) {
    RTC_LOG(LS_ERROR) << "Stream unable to use requested channel count";
    return false;
  }
  if (AAudioStream_getFormat(stream_) != AAUDIO_FORMAT_PCM_I16) {
    RTC_LOG(LS_ERROR) << "Stream unable to use requested format";
    return false;
  }
  if (AAudioStream_getSharingMode(stream_) != AAUDIO_SHARING_MODE_SHARED) {
    RTC_LOG(LS_ERROR) << "Stream unable to use requested sharing mode";
    return false;
  }
  if (AAudioStream_getPerformanceMode(stream_) !=
      AAUDIO_PERFORMANCE_MODE_LOW_LATENCY) {
    RTC_LOG(LS_ERROR) << "Stream unable to use requested performance mode";
    return false;
  }
  if (AAudioStream_getDirection(stream_) != direction()) {
    RTC_LOG(LS_ERROR) << "Stream direction could not be set";
    return false;
  }
  if (AAudioStream_getSamplesPerFrame(stream_) !=
      static_cast<int32_t>(audio_parameters().channels())) {
    RTC_LOG(LS_ERROR) << "Invalid number of samples per frame";
    return false;
  }
  return true;
}

bool AAudioWrapper::OptimizeBuffers() {
  RTC_LOG(INFO) << "OptimizeBuffers";
  RTC_DCHECK(stream_);
  // Maximum number of frames that can be filled without blocking.
  RTC_LOG(INFO) << "max buffer capacity in frames: "
                << buffer_capacity_in_frames();
  // Query the number of frames that the application should read or write at
  // one time for optimal performance.
  int32_t frames_per_burst = AAudioStream_getFramesPerBurst(stream_);
  RTC_LOG(INFO) << "frames per burst for optimal performance: "
                << frames_per_burst;
  frames_per_burst_ = frames_per_burst;
  if (direction() == AAUDIO_DIRECTION_INPUT) {
    // There is no point in calling setBufferSizeInFrames() for input streams
    // since it has no effect on the performance (latency in this case).
    return true;
  }
  // Set buffer size to same as burst size to guarantee lowest possible latency.
  // This size might change for output streams if underruns are detected and
  // automatic buffer adjustment is enabled.
  AAudioStream_setBufferSizeInFrames(stream_, frames_per_burst);
  int32_t buffer_size = AAudioStream_getBufferSizeInFrames(stream_);
  if (buffer_size != frames_per_burst) {
    RTC_LOG(LS_ERROR) << "Failed to use optimal buffer burst size";
    return false;
  }
  // Maximum number of frames that can be filled without blocking.
  RTC_LOG(INFO) << "buffer burst size in frames: " << buffer_size;
  return true;
}

}  // namespace webrtc
