// Copyright 2015 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 <limits>
#include <set>

#include "mojo/services/media/common/cpp/local_time.h"
#include "services/media/audio/platform/linux/alsa_output.h"

namespace mojo {
namespace media {
namespace audio {

constexpr LocalDuration AlsaOutput::kChunkDuration;
constexpr uint32_t AlsaOutput::kLowBufThreshChunks;
constexpr uint32_t AlsaOutput::kTargetLatencyChunks;
constexpr LocalDuration AlsaOutput::kLowBufThresh;
constexpr LocalDuration AlsaOutput::kTargetLatency;

static constexpr LocalDuration kErrorRecoveryTime = local_time::from_msec(300);
static constexpr LocalDuration kWaitForAlsaDelay  = local_time::from_usec(500);
static const std::set<uint8_t> kSupportedChannelCounts({ 1, 2 });
static const std::set<uint32_t> kSupportedSampleRates({
    48000, 32000, 24000, 16000, 8000, 4000,
    44100, 22050, 11025,
});

static inline bool IsRecoverableAlsaError(int error_code) {
  switch (error_code) {
  case -EINTR:
  case -EPIPE:
  case -ESTRPIPE:
    return true;
  default:
    return false;
  }
}

AudioOutputPtr CreateDefaultAlsaOutput(AudioOutputManager* manager) {
  // TODO(johngro): Do better than this.  If we really want to support
  // Linux/ALSA as a platform, we should be creating one output for each
  // physical output in the system, matching our configuration to the physical
  // output's configuration, and disabling resampling at the ALSA level.
  //
  // If we could own the output entirely and bypass the mixer to achieve lower
  // latency, that would be even better.
  AudioOutputPtr audio_out(audio::AlsaOutput::New(manager));
  if (!audio_out) { return nullptr; }

  AlsaOutput* alsa_out = static_cast<AlsaOutput*>(audio_out.get());
  DCHECK(alsa_out);

  LpcmMediaTypeDetailsPtr config(LpcmMediaTypeDetails::New());
  config->frames_per_second = 48000;
  config->channels = 2;
  config->sample_format = LpcmSampleFormat::SIGNED_16;

  if (alsa_out->Configure(config.Pass()) != MediaResult::OK) {
    return nullptr;
  }

  return audio_out;
}

AlsaOutput::AlsaOutput(AudioOutputManager* manager)
  : StandardOutputBase(manager) {}

AlsaOutput::~AlsaOutput() {
  // We should have been cleaned up already, but in release builds, call cleanup
  // anyway, just in case something got missed.
  DCHECK(!alsa_device_);
  Cleanup();
}

AudioOutputPtr AlsaOutput::New(AudioOutputManager* manager) {
  return AudioOutputPtr(new AlsaOutput(manager));
}

MediaResult AlsaOutput::Configure(LpcmMediaTypeDetailsPtr config) {
  if (!config) { return MediaResult::INVALID_ARGUMENT; }
  if (output_formatter_) { return MediaResult::BAD_STATE; }

  output_formatter_ = OutputFormatter::Select(config);
  if (!output_formatter_) { return MediaResult::UNSUPPORTED_CONFIG; }

  MediaResult res = AlsaSelectFormat(config);
  if (res != MediaResult::OK) { return res; }
  DCHECK_GE(alsa_format_, 0);

  if (kSupportedSampleRates.find(config->frames_per_second) ==
      kSupportedSampleRates.end()) {
    return MediaResult::UNSUPPORTED_CONFIG;
  }

  if (kSupportedChannelCounts.find(config->channels) ==
      kSupportedChannelCounts.end()) {
    return MediaResult::UNSUPPORTED_CONFIG;
  }

  // Compute the ratio between frames and local time ticks.
  LinearTransform::Ratio sec_per_tick(LocalDuration::period::num,
                                      LocalDuration::period::den);
  LinearTransform::Ratio frames_per_sec(config->frames_per_second, 1);
  bool is_precise = LinearTransform::Ratio::Compose(frames_per_sec,
                                                    sec_per_tick,
                                                    &frames_per_tick_);
  DCHECK(is_precise);

  // Success
  return MediaResult::OK;
}

MediaResult AlsaOutput::Init() {
  if (!output_formatter_) { return MediaResult::BAD_STATE; }
  if (alsa_device_) { return MediaResult::BAD_STATE; }

  MediaResult res = AlsaOpen();
  if (res != MediaResult::OK) {
    Cleanup();
    return res;
  }
  DCHECK(mix_buf_frames_);

  size_t buffer_size;
  buffer_size = mix_buf_frames_ * output_formatter_->bytes_per_frame();
  mix_buf_.reset(new uint8_t[buffer_size]);

  // Set up the intermediate buffer at the StandardOutputBase level
  SetupMixBuffer(mix_buf_frames_);

  return MediaResult::OK;
}

void AlsaOutput::Cleanup() {
  AlsaClose();
  DCHECK(!alsa_device_);

  mix_buf_ = nullptr;
  mix_buf_frames_ = 0;
}

bool AlsaOutput::StartMixJob(MixJob* job, const LocalTime& process_start) {
  DCHECK(job);
  DCHECK(alsa_device_);

  // Are we not primed?  If so, fill a mix buffer with silence and send it to
  // the alsa device.  Schedule a callback for a short time in the future so
  // ALSA has a chance to start the output and we can take our best guess of the
  // function which maps output frames to local time.
  if (!primed_) {
    HandleAsUnderflow();
    return false;
  }

  // Figure out how many frames of audio we need to produce in order to top off
  // the buffer.  If we are primed, but do not know the transformation between
  // audio frames and local time ticks, do our best to figure it out in the
  // process.
  int res;
  uint32_t avail;
  if (!local_to_output_known_) {
    uint32_t delay;
    res = AlsaGetAvailDelay(&avail, &delay);
    LocalTime now = LocalClock::now();

    // When using the FNL tinyalsa implementation, if we have queued enough data
    // to start, but have not actually started yet, the implementation will
    // return EAGAIN to indicate that we are going to start "Real Soon Now".
    // Wait just a bit, then try again.
    if (res == -EAGAIN) {
      SetNextSchedDelay(local_time::from_msec(1));
      return false;
    }

    if (res < 0) {
      HandleAlsaError(res);
      return false;
    }

    int64_t now_ticks = now.time_since_epoch().count();
    local_to_output_ = LinearTransform(now_ticks,
                                       frames_per_tick_,
                                       -static_cast<int64_t>(delay));
    local_to_output_known_ = true;
    frames_sent_ = 0;
    while (++local_to_output_gen_ == MixJob::INVALID_GENERATION) {}
  } else {
    res = AlsaGetAvailDelay(&avail);
    if (res < 0) {
      HandleAlsaError(res);
      return false;
    }
  }

  // Compute the time that we think we will completely underflow, then back off
  // from that by the low buffer threshold and use that to determine when we
  // should mix again.
  int64_t playout_time_ticks;
  bool trans_ok = local_to_output_.DoReverseTransform(frames_sent_,
                                                      &playout_time_ticks);
  DCHECK(trans_ok);
  LocalTime playout_time = LocalTime(LocalDuration(playout_time_ticks));
  LocalTime low_buf_time = playout_time - kLowBufThresh;

  if (process_start >= low_buf_time) {
    // Because of the way that ALSA consumes data and updates its internal
    // bookkeeping, it is possible that we are past our low buffer threshold,
    // but ALSA still thinks that there is no room to write new frames.  If this
    // is the case, just try again a short amount of time in the future.
    if (!avail) {
      SetNextSchedDelay(kWaitForAlsaDelay);
      return false;
    }

    // Limit the amt that we queue to be no more than what ALSA will currently
    // accept, or what it currently will take to fill us to our target latency.
    //
    // The playout target had better be ahead of the playout time, or we are
    // almost certainly going to underflow.  If this happens, for whatever
    // reason, just try to send a full buffer and deal with the underflow when
    // ALSA notices it.
    int64_t fill_amt;
    LocalTime now = LocalClock::now();
    LocalTime playout_target = now + kTargetLatency;
    if (playout_target > playout_time) {
      fill_amt = (playout_target - playout_time).count();
    } else {
      fill_amt = kTargetLatency.count();
    }

    DCHECK_GE(fill_amt, 0);
    DCHECK_LE(fill_amt, std::numeric_limits<int32_t>::max());
    fill_amt *= frames_per_tick_.numerator;
    fill_amt += frames_per_tick_.denominator - 1;
    fill_amt /= frames_per_tick_.denominator;

    job->buf_frames = (avail < fill_amt) ? avail : fill_amt;
    if (job->buf_frames > mix_buf_frames_) {
      job->buf_frames = mix_buf_frames_;
    }

    job->buf = mix_buf_.get();
    job->start_pts_of = frames_sent_;
    job->local_to_output = &local_to_output_;
    job->local_to_output_gen = local_to_output_gen_;

    return true;
  }

  // Wait until its time to mix some more data.
  SetNextSchedTime(low_buf_time);
  return false;
}

bool AlsaOutput::FinishMixJob(const MixJob& job) {
  DCHECK(job.buf == mix_buf_.get());
  DCHECK(job.buf_frames);

  // We should always be able to write all of the data that we mixed.
  int res;
  res = AlsaWrite(job.buf, job.buf_frames);
  if (static_cast<unsigned int>(res) != job.buf_frames) {
    HandleAlsaError(res);
    return false;
  }

  frames_sent_ += res;
  return true;
}

void AlsaOutput::HandleAsUnderflow() {
  int res;

  // If we were already primed, then this is a legitimate underflow, not the
  // startup case or recovery from some other error.
  if (primed_) {
    // TODO(johngro): come up with a way to properly throttle this.  Also, add a
    // friendly name to the output so the log helps to identify which output
    // underflowed.
    LOG(WARNING) << "[" << this << "] : underflow";
    res = AlsaRecover(-EPIPE);
    if (res < 0) {
      HandleAsError(res);
      return;
    }
  }

  // TODO(johngro): We don't actually have to fill up the entire lead time with
  // silence.  When we have better control of our thread priorities, prime this
  // with the minimimum amt we can get away with and still be able to start
  // mixing without underflowing.
  output_formatter_->FillWithSilence(mix_buf_.get(), mix_buf_frames_);
  res = AlsaWrite(mix_buf_.get(), mix_buf_frames_);

  if (res < 0) {
    HandleAsError(res);
    return;
  }

  primed_ = true;
  local_to_output_known_ = false;
  SetNextSchedDelay(local_time::from_msec(1));
}

void AlsaOutput::HandleAsError(int code) {
  if (IsRecoverableAlsaError(code)) {
    // TODO(johngro): Throttle this somehow.
    LOG(WARNING) << "[" << this << "] : Attempting to recover from ALSA error "
                 << code;

    int new_code = AlsaRecover(code);
    DCHECK(!new_code || (new_code == code));

    // If we recovered, or we didn't and the original error was EINTR, schedule
    // a retry time in the future and unwind.
    //
    // TODO(johngro): revisit the topic of errors we fail to snd_pcm_recover
    // from.  If we cannot recover from them, we should probably close and
    // re-open the device.  No matter what, we should put some form of limit on
    // how many times we try before really giving up and shutting down the
    // output for good.  We also need to invent a good way to test these edge
    // cases.
    if (!new_code || (new_code == -EINTR)) {
      primed_ = false;
      local_to_output_known_ = false;
      SetNextSchedDelay(kErrorRecoveryTime);
    }
  }

  LOG(ERROR) << "[" << this << "] : Fatal ALSA error "
             << code << ".  Shutting down";
  ShutdownSelf();
}

void AlsaOutput::HandleAlsaError(int code) {
  // ALSA signals an underflow by returning -EPIPE from jobs.  If the error code
  // is -EPIPE, treat this as an underflow and attempt to reprime the pipeline.
  if (code == -EPIPE) {
    HandleAsUnderflow();
  } else {
    HandleAsError(code);
  }
}

}  // namespace audio
}  // namespace media
}  // namespace mojo
