// Copyright 2013 The Chromium 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/audio/alsa/alsa_util.h"

#include <stddef.h>

#include <functional>
#include <memory>

#include "base/logging.h"
#include "base/time/time.h"
#include "media/audio/alsa/alsa_wrapper.h"

namespace alsa_util {

namespace {

// Set hardware parameters of PCM. It does the same thing as the corresponding
// part in snd_pcm_set_params() (https://www.alsa-project.org, source code:
// https://github.com/tiwai/alsa-lib/blob/master/src/pcm/pcm.c#L8459), except
// that it configures buffer size and period size both to closest available
// values instead of forcing the buffer size be 4 times of the period size.
int ConfigureHwParams(media::AlsaWrapper* wrapper,
                      snd_pcm_t* handle,
                      snd_pcm_format_t format,
                      snd_pcm_access_t access,
                      unsigned int channels,
                      unsigned int sample_rate,
                      int soft_resample,
                      snd_pcm_uframes_t frames_per_buffer,
                      snd_pcm_uframes_t frames_per_period) {
  int error = 0;

  snd_pcm_hw_params_t* hw_params = nullptr;
  error = wrapper->PcmHwParamsMalloc(&hw_params);
  if (error < 0) {
    LOG(ERROR) << "PcmHwParamsMalloc: " << wrapper->StrError(error);
    return error;
  }
  // |snd_pcm_hw_params_t| is not exposed and requires memory allocation through
  // ALSA API. Therefore, use a smart pointer to pointer to insure freeing
  // memory when the function returns.
  std::unique_ptr<snd_pcm_hw_params_t*,
                  std::function<void(snd_pcm_hw_params_t**)>>
      params_holder(&hw_params, [wrapper](snd_pcm_hw_params_t** params) {
        wrapper->PcmHwParamsFree(*params);
      });

  error = wrapper->PcmHwParamsAny(handle, hw_params);
  if (error < 0) {
    LOG(ERROR) << "PcmHwParamsAny: " << wrapper->StrError(error);
    return error;
  }

  error = wrapper->PcmHwParamsSetRateResample(handle, hw_params, soft_resample);
  if (error < 0) {
    LOG(ERROR) << "PcmHwParamsSetRateResample: " << wrapper->StrError(error);
    return error;
  }

  error = wrapper->PcmHwParamsSetAccess(handle, hw_params, access);
  if (error < 0) {
    LOG(ERROR) << "PcmHwParamsSetAccess: " << wrapper->StrError(error);
    return error;
  }

  error = wrapper->PcmHwParamsSetFormat(handle, hw_params, format);
  if (error < 0) {
    LOG(ERROR) << "PcmHwParamsSetFormat: " << wrapper->StrError(error);
    return error;
  }

  error = wrapper->PcmHwParamsSetChannels(handle, hw_params, channels);
  if (error < 0) {
    LOG(ERROR) << "PcmHwParamsSetChannels: " << wrapper->StrError(error);
    return error;
  }

  unsigned int rate = sample_rate;
  error = wrapper->PcmHwParamsSetRateNear(handle, hw_params, &rate, nullptr);
  if (error < 0) {
    LOG(ERROR) << "PcmHwParamsSetRateNear: " << wrapper->StrError(error);
    return error;
  }
  if (rate != sample_rate) {
    LOG(ERROR) << "Rate doesn't match, required: " << sample_rate
               << "Hz, but get: " << rate << "Hz.";
    return -EINVAL;
  }

  error = wrapper->PcmHwParamsSetBufferSizeNear(handle, hw_params,
                                                &frames_per_buffer);
  if (error < 0) {
    LOG(ERROR) << "PcmHwParamsSetBufferSizeNear: " << wrapper->StrError(error);
    return error;
  }

  int direction = 0;
  error = wrapper->PcmHwParamsSetPeriodSizeNear(handle, hw_params,
                                                &frames_per_period, &direction);
  if (error < 0) {
    LOG(ERROR) << "PcmHwParamsSetPeriodSizeNear: " << wrapper->StrError(error);
    return error;
  }

  if (frames_per_period > frames_per_buffer / 2) {
    LOG(ERROR) << "Period size (" << frames_per_period
               << ") is too big; buffer size = " << frames_per_buffer;
    return -EINVAL;
  }

  error = wrapper->PcmHwParams(handle, hw_params);
  if (error < 0)
    LOG(ERROR) << "PcmHwParams: " << wrapper->StrError(error);

  return error;
}

// Set software parameters of PCM. It does the same thing as the corresponding
// part in snd_pcm_set_params()
// (https://github.com/tiwai/alsa-lib/blob/master/src/pcm/pcm.c#L8603).
int ConfigureSwParams(media::AlsaWrapper* wrapper,
                      snd_pcm_t* handle,
                      snd_pcm_uframes_t frames_per_buffer,
                      snd_pcm_uframes_t frames_per_period) {
  int error = 0;

  snd_pcm_sw_params_t* sw_params = nullptr;
  error = wrapper->PcmSwParamsMalloc(&sw_params);
  if (error < 0) {
    LOG(ERROR) << "PcmSwParamsMalloc: " << wrapper->StrError(error);
    return error;
  }
  // |snd_pcm_sw_params_t| is not exposed and thus use a smart pointer to
  // pointer to insure freeing memory when the function returns.
  std::unique_ptr<snd_pcm_sw_params_t*,
                  std::function<void(snd_pcm_sw_params_t**)>>
      params_holder(&sw_params, [wrapper](snd_pcm_sw_params_t** params) {
        wrapper->PcmSwParamsFree(*params);
      });

  error = wrapper->PcmSwParamsCurrent(handle, sw_params);
  if (error < 0) {
    LOG(ERROR) << "PcmSwParamsCurrent: " << wrapper->StrError(error);
    return error;
  }

  // For playback, start the transfer when the buffer is almost full.
  int start_threshold =
      (frames_per_buffer / frames_per_period) * frames_per_period;
  error =
      wrapper->PcmSwParamsSetStartThreshold(handle, sw_params, start_threshold);
  if (error < 0) {
    LOG(ERROR) << "PcmSwParamsSetStartThreshold: " << wrapper->StrError(error);
    return error;
  }

  // For capture, wake capture thread as soon as possible (1 period).
  error = wrapper->PcmSwParamsSetAvailMin(handle, sw_params, frames_per_period);
  if (error < 0) {
    LOG(ERROR) << "PcmSwParamsSetAvailMin: " << wrapper->StrError(error);
    return error;
  }

  error = wrapper->PcmSwParams(handle, sw_params);
  if (error < 0)
    LOG(ERROR) << "PcmSwParams: " << wrapper->StrError(error);

  return error;
}

int SetParams(media::AlsaWrapper* wrapper,
              snd_pcm_t* handle,
              snd_pcm_format_t format,
              unsigned int channels,
              unsigned int rate,
              unsigned int frames_per_buffer,
              unsigned int frames_per_period) {
  int error = ConfigureHwParams(
      wrapper, handle, format, SND_PCM_ACCESS_RW_INTERLEAVED, channels, rate,
      1 /* Enable resampling */, frames_per_buffer, frames_per_period);
  if (error == 0) {
    error = ConfigureSwParams(wrapper, handle, frames_per_buffer,
                              frames_per_period);
  }
  return error;
}

}  // namespace

static snd_pcm_t* OpenDevice(media::AlsaWrapper* wrapper,
                             const char* device_name,
                             snd_pcm_stream_t type,
                             int channels,
                             int sample_rate,
                             snd_pcm_format_t pcm_format,
                             int buffer_us,
                             int period_us = 0) {
  snd_pcm_t* handle = NULL;
  int error = wrapper->PcmOpen(&handle, device_name, type, SND_PCM_NONBLOCK);
  if (error < 0) {
    LOG(ERROR) << "PcmOpen: " << device_name << "," << wrapper->StrError(error);
    return NULL;
  }

  error =
      wrapper->PcmSetParams(handle, pcm_format, SND_PCM_ACCESS_RW_INTERLEAVED,
                            channels, sample_rate, 1, buffer_us);
  if (error < 0) {
    LOG(WARNING) << "PcmSetParams: " << device_name << ", "
                 << wrapper->StrError(error);
    // Default parameter setting function failed, try again with the customized
    // one if |period_us| is set, which is the case for capture but not for
    // playback.
    if (period_us > 0) {
      const unsigned int frames_per_buffer = static_cast<unsigned int>(
          static_cast<int64_t>(buffer_us) * sample_rate /
          base::Time::kMicrosecondsPerSecond);
      const unsigned int frames_per_period = static_cast<unsigned int>(
          static_cast<int64_t>(period_us) * sample_rate /
          base::Time::kMicrosecondsPerSecond);
      LOG(WARNING) << "SetParams: " << device_name
                   << " - Format: " << pcm_format << " Channels: " << channels
                   << " Sample rate: " << sample_rate
                   << " Buffer size: " << frames_per_buffer
                   << " Period size: " << frames_per_period;
      error = SetParams(wrapper, handle, pcm_format, channels, sample_rate,
                        frames_per_buffer, frames_per_period);
    }
  }
  if (error < 0) {
    if (alsa_util::CloseDevice(wrapper, handle) < 0) {
      // TODO(ajwong): Retry on certain errors?
      LOG(WARNING) << "Unable to close audio device. Leaking handle.";
    }
    return NULL;
  }

  return handle;
}

static std::string DeviceNameToControlName(const std::string& device_name) {
  const char kMixerPrefix[] = "hw";
  std::string control_name;
  size_t pos1 = device_name.find(':');
  if (pos1 == std::string::npos) {
    control_name = device_name;
  } else {
    // Examples:
    // deviceName: "front:CARD=Intel,DEV=0", controlName: "hw:CARD=Intel".
    // deviceName: "default:CARD=Intel", controlName: "CARD=Intel".
    size_t pos2 = device_name.find(',');
    control_name = (pos2 == std::string::npos)
                       ? device_name.substr(pos1 + 1)
                       : kMixerPrefix + device_name.substr(pos1, pos2 - pos1);
  }

  return control_name;
}

int CloseDevice(media::AlsaWrapper* wrapper, snd_pcm_t* handle) {
  std::string device_name = wrapper->PcmName(handle);
  int error = wrapper->PcmClose(handle);
  if (error < 0) {
    LOG(ERROR) << "PcmClose: " << device_name << ", "
               << wrapper->StrError(error);
  }

  return error;
}

snd_pcm_t* OpenCaptureDevice(media::AlsaWrapper* wrapper,
                             const char* device_name,
                             int channels,
                             int sample_rate,
                             snd_pcm_format_t pcm_format,
                             int buffer_us,
                             int period_us) {
  return OpenDevice(wrapper, device_name, SND_PCM_STREAM_CAPTURE, channels,
                    sample_rate, pcm_format, buffer_us, period_us);
}

snd_pcm_t* OpenPlaybackDevice(media::AlsaWrapper* wrapper,
                              const char* device_name,
                              int channels,
                              int sample_rate,
                              snd_pcm_format_t pcm_format,
                              int buffer_us) {
  return OpenDevice(wrapper, device_name, SND_PCM_STREAM_PLAYBACK, channels,
                    sample_rate, pcm_format, buffer_us);
}

snd_mixer_t* OpenMixer(media::AlsaWrapper* wrapper,
                       const std::string& device_name) {
  snd_mixer_t* mixer = NULL;

  int error = wrapper->MixerOpen(&mixer, 0);
  if (error < 0) {
    LOG(ERROR) << "MixerOpen: " << device_name << ", "
               << wrapper->StrError(error);
    return NULL;
  }

  std::string control_name = DeviceNameToControlName(device_name);
  error = wrapper->MixerAttach(mixer, control_name.c_str());
  if (error < 0) {
    LOG(ERROR) << "MixerAttach, " << control_name << ", "
               << wrapper->StrError(error);
    alsa_util::CloseMixer(wrapper, mixer, device_name);
    return NULL;
  }

  error = wrapper->MixerElementRegister(mixer, NULL, NULL);
  if (error < 0) {
    LOG(ERROR) << "MixerElementRegister: " << control_name << ", "
               << wrapper->StrError(error);
    alsa_util::CloseMixer(wrapper, mixer, device_name);
    return NULL;
  }

  return mixer;
}

void CloseMixer(media::AlsaWrapper* wrapper, snd_mixer_t* mixer,
                const std::string& device_name) {
  if (!mixer)
    return;

  wrapper->MixerFree(mixer);

  int error = 0;
  if (!device_name.empty()) {
    std::string control_name = DeviceNameToControlName(device_name);
    error = wrapper->MixerDetach(mixer, control_name.c_str());
    if (error < 0) {
      LOG(WARNING) << "MixerDetach: " << control_name << ", "
                   << wrapper->StrError(error);
    }
  }

  error = wrapper->MixerClose(mixer);
  if (error < 0) {
    LOG(WARNING) << "MixerClose: " << wrapper->StrError(error);
  }
}

snd_mixer_elem_t* LoadCaptureMixerElement(media::AlsaWrapper* wrapper,
                                          snd_mixer_t* mixer) {
  if (!mixer)
    return NULL;

  int error = wrapper->MixerLoad(mixer);
  if (error < 0) {
    LOG(ERROR) << "MixerLoad: " << wrapper->StrError(error);
    return NULL;
  }

  snd_mixer_elem_t* elem = NULL;
  snd_mixer_elem_t* mic_elem = NULL;
  const char kCaptureElemName[] = "Capture";
  const char kMicElemName[] = "Mic";
  for (elem = wrapper->MixerFirstElem(mixer);
       elem;
       elem = wrapper->MixerNextElem(elem)) {
    if (wrapper->MixerSelemIsActive(elem)) {
      const char* elem_name = wrapper->MixerSelemName(elem);
      if (strcmp(elem_name, kCaptureElemName) == 0)
        return elem;
      else if (strcmp(elem_name, kMicElemName) == 0)
        mic_elem = elem;
    }
  }

  // Did not find any Capture handle, use the Mic handle.
  return mic_elem;
}

}  // namespace alsa_util
