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