// Copyright 2018 The Chromium OS 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 "media_perception/audio_receiver.h"

#include <alsa/asoundlib.h>
#include <utility>

#include "base/logging.h"

namespace mri {

namespace {

// Callback when getting a new audio frame.
int OnAudioSamples(struct cras_client* client,
                   cras_stream_id_t stream_id,
                   uint8_t* captured_samples,
                   uint8_t* playback_samples,
                   unsigned int num_samples,
                   const struct timespec* captured_time,
                   const struct timespec* playback_time,
                   void* user_arg) {
  mri::AudioReceiver* audio_receiver = (mri::AudioReceiver*)user_arg;
  audio_receiver->ProcessAudioSamples(captured_samples, num_samples);
  return num_samples;
}

// Callback when getting audio capture error.
int OnAudioCaptureError(struct cras_client* client,
                        cras_stream_id_t stream_id,
                        int err,
                        void* arg) {
  LOG(ERROR) << "Audio capture error with code: " << err;
  return err;
}

}  // namespace

void AudioReceiver::ProcessAudioSamples(const uint8_t* samples,
                                        unsigned int num_frames) {
  const int bytes_per_frame = cras_client_format_bytes_per_frame(audio_format_);
  const int total_bytes = bytes_per_frame * num_frames;
  for (auto& handler_pair : frame_handler_id_to_audio_frame_handler_map_) {
    handler_pair.second(samples, total_bytes);
  }
}

AudioReceiver::AudioReceiver(const std::string& device_id)
    : device_id_(device_id), frame_handler_counter_(0) {}

bool AudioReceiver::CaptureFormatMatches(const AudioStreamParams& requested) {
  return params_.frequency_in_hz() == requested.frequency_in_hz() &&
         params_.num_channels() == requested.num_channels() &&
         params_.frame_size() == requested.frame_size() &&
         params_.sample_format() == requested.sample_format();
}

int AudioReceiver::GetFrameHandlerCount() {
  return frame_handler_id_to_audio_frame_handler_map_.size();
}

bool AudioReceiver::SetAudioStreamParams(const AudioStreamParams& params) {
  DestroyParams();

  snd_pcm_format_t sample_format;
  switch (params.sample_format()) {
    case SampleFormat::SND_PCM_FORMAT_S32_LE:
      sample_format = ::SND_PCM_FORMAT_S32_LE;
      break;
    case SampleFormat::SND_PCM_FORMAT_S16_LE:
      sample_format = ::SND_PCM_FORMAT_S16_LE;
      break;
    default:
      LOG(ERROR) << "Sample format unknown or not supported.";
      return false;
  }

  audio_format_ = cras_audio_format_create(
      sample_format, params.frequency_in_hz(), params.num_channels());
  if (!audio_format_) {
    LOG(ERROR) << "Failed to create CrAS audio format.";
    DestroyParams();
    return false;
  }

  audio_capture_params_ = cras_client_unified_params_create(
      CRAS_STREAM_INPUT, params.frame_size(), CRAS_STREAM_TYPE_DEFAULT, 0, this,
      OnAudioSamples, OnAudioCaptureError, audio_format_);
  if (!audio_capture_params_) {
    LOG(ERROR) << "Failed to create CrAS audio capture format.";
    DestroyParams();
    return false;
  }

  params_ = params;
  return true;
}

AudioStreamParams AudioReceiver::GetAudioStreamParams() {
  return params_;
}

bool AudioReceiver::StartAudioCaptureForDeviceIdx(struct cras_client* client,
                                                  int dev_idx) {
  // Create a pinned stream. Return 0 on success, or negative error code on
  // failure.
  int rc = cras_client_add_pinned_stream(client, dev_idx, &stream_id_,
                                         audio_capture_params_);
  if (rc != 0) {
    LOG(ERROR) << "Failed to add pinned stream with error code: " << rc;
    return false;
  }
  return true;
}

int AudioReceiver::AddAudioFrameHandler(
    ChromeAudioServiceClient::AudioFrameHandler handler) {
  frame_handler_counter_++;
  frame_handler_id_to_audio_frame_handler_map_[frame_handler_counter_] =
      std::move(handler);
  return frame_handler_counter_;
}

bool AudioReceiver::RemoveFrameHandler(int frame_handler_id) {
  if (frame_handler_id_to_audio_frame_handler_map_.find(frame_handler_id) ==
      frame_handler_id_to_audio_frame_handler_map_.end()) {
    // Frame handler not found.
    return false;
  }

  frame_handler_id_to_audio_frame_handler_map_.erase(frame_handler_id);
  return true;
}

void AudioReceiver::StopAudioCapture(struct cras_client* client) {
  cras_client_rm_stream(client, stream_id_);
}

void AudioReceiver::DestroyParams() {
  if (audio_format_) {
    cras_audio_format_destroy(audio_format_);
    audio_format_ = nullptr;
  }

  if (audio_capture_params_) {
    cras_client_stream_params_destroy(audio_capture_params_);
    audio_capture_params_ = nullptr;
  }
}

}  // namespace mri
