// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/alsa/alsa_audio_sink_type.h"

#include <algorithm>
#include <vector>

#include "starboard/common/condition_variable.h"
#include "starboard/common/mutex.h"
#include "starboard/configuration.h"
#include "starboard/contrib/tizen/shared/alsa/alsa_util.h"
#include "starboard/memory.h"
#include "starboard/thread.h"
#include "starboard/time.h"

namespace starboard {
namespace shared {
namespace alsa {
namespace {

using starboard::ScopedLock;
using starboard::ScopedTryLock;
using starboard::shared::alsa::AlsaGetBufferedFrames;
using starboard::shared::alsa::AlsaWriteFrames;

// The maximum number of frames that can be written to ALSA once.  It must be a
// power of 2.  It is also used as the ALSA polling size.  A small number will
// lead to more CPU being used as the callbacks will be called more
// frequently and also it will be more likely to cause underflow but can make
// the audio clock more accurate.
const int kFramesPerRequest = 512;
// When the frames inside ALSA buffer is less than |kMinimumFramesInALSA|, the
// class will try to write more frames.  The larger the number is, the less
// likely an underflow will happen but to use a larger number will cause longer
// delays after pause and stop.
const int kMinimumFramesInALSA = 2048;
// The size of the audio buffer ALSA allocates internally.  Ideally this value
// should be greater than the sum of the above two constants.  Choose a value
// that is too large can waste some memory as the extra buffer is never used.
const int kALSABufferSizeInFrames = 8192;
// Helper function to compute the size of the two valid starboard audio sample
// types.

size_t GetSampleSize(SbMediaAudioSampleType sample_type) {
  switch (sample_type) {
    case kSbMediaAudioSampleTypeFloat32:
      return sizeof(float);
    case kSbMediaAudioSampleTypeInt16Deprecated:
      return sizeof(int16_t);
  }
  SB_NOTREACHED();
  return 0u;
}

size_t GetBytesPerFrame(int channels, SbMediaAudioSampleType sample_type) {
  return sizeof(uint8_t) * channels * GetSampleSize(sample_type);
}

void* IncrementPointerByBytes(void* pointer, size_t offset) {
  return static_cast<void*>(static_cast<uint8_t*>(pointer) + offset);
}

// This class is an ALSA based audio sink with the following features:
// 1. It doesn't cache any data internally and maintains minimum data inside
//    the ALSA buffer.  It relies on pulling data from its source in high
//    frequency to playback audio.
// 2. It never stops the underlying ALSA audio sink once created.  When its
//    source cannot provide enough data to continue playback, it simply writes
//    silence to ALSA.
class AlsaAudioSink : public SbAudioSinkPrivate {
 public:
  AlsaAudioSink(Type* type,
                int channels,
                int sampling_frequency_hz,
                SbMediaAudioSampleType sample_type,
                SbAudioSinkFrameBuffers frame_buffers,
                int frames_per_channel,
                SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
                SbAudioSinkConsumeFramesFunc consume_frame_func,
                void* context);
  ~AlsaAudioSink() override;

  bool IsType(Type* type) override { return type_ == type; }

  void SetPlaybackRate(double playback_rate) override {
    ScopedLock lock(mutex_);
    playback_rate_ = playback_rate;
  }

  void SetVolume(double volume) override {
    ScopedLock lock(mutex_);
    volume_ = volume;
  }

  bool is_valid() { return playback_handle_ != NULL; }

 private:
  static void* ThreadEntryPoint(void* context);
  void AudioThreadFunc();
  // Write silence to ALSA when there is not enough data in source or when the
  // sink is paused.
  // Return true to continue to play.  Return false when destroying.
  bool IdleLoop();
  // Keep pulling frames from source until there is no frames to keep playback.
  // When the sink is paused or there is no frames in source, it returns true
  // so we can continue into the IdleLoop().  It returns false when destroying.
  bool PlaybackLoop();
  // Helper function to write frames contained in a ring buffer to ALSA.
  void WriteFrames(double playback_rate,
                   int frames_to_write,
                   int frames_in_buffer,
                   int offset_in_frames);

  Type* type_;
  SbAudioSinkUpdateSourceStatusFunc update_source_status_func_;
  SbAudioSinkConsumeFramesFunc consume_frame_func_;
  void* context_;

  double playback_rate_;
  double volume_;
  std::vector<uint8_t> resample_buffer_;

  int channels_;
  int sampling_frequency_hz_;
  SbMediaAudioSampleType sample_type_;
  int bytes_per_frame_;

  SbThread audio_out_thread_;
  starboard::Mutex mutex_;
  starboard::ConditionVariable creation_signal_;

  SbTime time_to_wait_;

  bool destroying_;

  void* frame_buffer_;
  int frames_per_channel_;
  void* silence_frames_;

  void* playback_handle_;
};

AlsaAudioSink::AlsaAudioSink(
    Type* type,
    int channels,
    int sampling_frequency_hz,
    SbMediaAudioSampleType sample_type,
    SbAudioSinkFrameBuffers frame_buffers,
    int frames_per_channel,
    SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
    SbAudioSinkConsumeFramesFunc consume_frame_func,
    void* context)
    : type_(type),
      playback_rate_(1.0),
      volume_(1.0),
      resample_buffer_(channels * kFramesPerRequest *
                       GetSampleSize(sample_type)),
      channels_(channels),
      sampling_frequency_hz_(sampling_frequency_hz),
      sample_type_(sample_type),
      bytes_per_frame_(GetBytesPerFrame(channels, sample_type)),
      update_source_status_func_(update_source_status_func),
      consume_frame_func_(consume_frame_func),
      context_(context),
      audio_out_thread_(kSbThreadInvalid),
      creation_signal_(mutex_),
      time_to_wait_(kFramesPerRequest * kSbTimeSecond / sampling_frequency_hz /
                    2),
      destroying_(false),
      frame_buffer_(frame_buffers[0]),
      frames_per_channel_(frames_per_channel),
      silence_frames_(new uint8_t[channels * kFramesPerRequest *
                                  GetSampleSize(sample_type)]),
      playback_handle_(NULL) {
  SB_DCHECK(update_source_status_func_);
  SB_DCHECK(consume_frame_func_);
  SB_DCHECK(frame_buffer_);
  SB_DCHECK(SbAudioSinkIsAudioSampleTypeSupported(sample_type_));

  SbMemorySet(silence_frames_, 0,
              channels * kFramesPerRequest * GetSampleSize(sample_type));

  ScopedLock lock(mutex_);
  audio_out_thread_ =
      SbThreadCreate(0, kSbThreadPriorityRealTime, kSbThreadNoAffinity, true,
                     "alsa_audio_out", &AlsaAudioSink::ThreadEntryPoint, this);
  SB_DCHECK(SbThreadIsValid(audio_out_thread_));
  creation_signal_.Wait();
}

AlsaAudioSink::~AlsaAudioSink() {
  {
    ScopedLock lock(mutex_);
    destroying_ = true;
  }
  SbThreadJoin(audio_out_thread_, NULL);

  delete[] static_cast<uint8_t*>(silence_frames_);
}

// static
void* AlsaAudioSink::ThreadEntryPoint(void* context) {
  SB_DCHECK(context);
  AlsaAudioSink* sink = reinterpret_cast<AlsaAudioSink*>(context);
  sink->AudioThreadFunc();

  return NULL;
}

void AlsaAudioSink::AudioThreadFunc() {
  pa_sample_format alsa_sample_type =
      sample_type_ == kSbMediaAudioSampleTypeFloat32 ? PA_SAMPLE_FLOAT32LE
                                                     : PA_SAMPLE_S16LE;
  playback_handle_ = starboard::shared::alsa::AlsaOpenPlaybackDevice(
      channels_, sampling_frequency_hz_, alsa_sample_type);
  {
    ScopedLock lock(mutex_);
    creation_signal_.Signal();
  }

  if (!playback_handle_) {
    return;
  }

  for (;;) {
    if (!IdleLoop()) {
      break;
    }
    if (!PlaybackLoop()) {
      break;
    }
  }

  starboard::shared::alsa::AlsaCloseDevice(playback_handle_);
  ScopedLock lock(mutex_);
  playback_handle_ = NULL;
}

bool AlsaAudioSink::IdleLoop() {
  SB_DLOG(INFO) << "alsa::AlsaAudioSink enters idle loop";

  bool drain = true;

  for (;;) {
    double playback_rate;
    {
      ScopedLock lock(mutex_);
      if (destroying_) {
        break;
      }
      playback_rate = playback_rate_;
    }
    int frames_in_buffer, offset_in_frames;
    bool is_playing, is_eos_reached;
    update_source_status_func_(&frames_in_buffer, &offset_in_frames,
                               &is_playing, &is_eos_reached, context_);
    if (is_playing && frames_in_buffer > 0 && playback_rate > 0.0) {
      return true;
    }
    if (drain) {
      drain = false;
      AlsaWriteFrames(playback_handle_, silence_frames_,
                      bytes_per_frame_ * kFramesPerRequest);
      AlsaDrain(playback_handle_);
    }
    SbThreadSleep(time_to_wait_);
  }

  return false;
}

bool AlsaAudioSink::PlaybackLoop() {
  SB_DLOG(INFO) << "alsa::AlsaAudioSink enters playback loop";

  // TODO: Also handle |volume_| here.
  double playback_rate = 1.0;
  for (;;) {
    {
      ScopedTryLock lock(mutex_);
      if (lock.is_locked()) {
        if (destroying_) {
          break;
        }
        playback_rate = playback_rate_;
      }
    }

    if (playback_rate == 0.0) {
      return true;
    }
    int frames_in_buffer, offset_in_frames;
    bool is_playing, is_eos_reached;
    update_source_status_func_(&frames_in_buffer, &offset_in_frames,
                               &is_playing, &is_eos_reached, context_);
    if (!is_playing || frames_in_buffer == 0) {
      return true;
    }
    WriteFrames(playback_rate, std::min(kFramesPerRequest, frames_in_buffer),
                frames_in_buffer, offset_in_frames);
  }

  return false;
}

void AlsaAudioSink::WriteFrames(double playback_rate,
                                int frames_to_write,
                                int frames_in_buffer,
                                int offset_in_frames) {
  if (playback_rate == 1.0) {
    SB_DCHECK(frames_to_write <= frames_in_buffer);

    int frames_to_buffer_end = frames_per_channel_ - offset_in_frames;
    if (frames_to_write > frames_to_buffer_end) {
      int consumed = frames_to_buffer_end;
      if (!AlsaWriteFrames(
              playback_handle_,
              IncrementPointerByBytes(frame_buffer_,
                                      offset_in_frames * bytes_per_frame_),
              frames_to_buffer_end * bytes_per_frame_))
        consumed = 0;
      consume_frame_func_(
          consumed,
#if SB_API_VERSION >= 12
          (SbTime)kSbTimeMax,  // Async audio frames reporting not supported
#endif // SB_API_VERSION >= 12
          context_);
      if (consumed != frames_to_buffer_end) {
        return;
      }

      frames_to_write -= frames_to_buffer_end;
      offset_in_frames = 0;
    }

    int consumed = frames_to_write;
    if (!AlsaWriteFrames(
            playback_handle_,
            IncrementPointerByBytes(frame_buffer_,
                                    offset_in_frames * bytes_per_frame_),
            bytes_per_frame_ * frames_to_write)) {
      consumed = 0;
    }
    consume_frame_func_(
        consumed,
#if SB_API_VERSION >= 12
        (SbTime)kSbTimeMax,  // Async audio frames reporting not supported
#endif // SB_API_VERSION >= 12
        context_);
  } else {
    // A very low quality resampler that simply shift the audio frames to play
    // at the right time.
    // TODO: The playback rate adjustment should be done in AudioRenderer.  We
    // should provide a default sinc resampler.
    double source_frames = 0.0;
    int buffer_size_in_frames = resample_buffer_.size() / bytes_per_frame_;
    int target_frames = 0;
    SB_DCHECK(buffer_size_in_frames <= frames_to_write);

    // Use |playback_rate| as the granularity of increment for source buffer.
    // For example, when |playback_rate| is 0.25, every time a frame is copied
    // to the target buffer, the offset of source buffer will be increased by
    // 0.25, this effectively repeat the same frame four times into the target
    // buffer and it takes 4 times longer to finish playing the frames.
    while (static_cast<int>(source_frames) < frames_in_buffer &&
           target_frames < buffer_size_in_frames) {
      const uint8_t* source_addr = static_cast<uint8_t*>(frame_buffer_);
      source_addr += static_cast<int>(offset_in_frames + source_frames) %
                     frames_per_channel_ * bytes_per_frame_;
      SbMemoryCopy(&resample_buffer_[0] + bytes_per_frame_ * target_frames,
                   source_addr, bytes_per_frame_);
      ++target_frames;
      source_frames += playback_rate;
    }

    int consumed = target_frames;
    if (!AlsaWriteFrames(playback_handle_, &resample_buffer_[0],
                         bytes_per_frame_ * target_frames)) {
      consumed = 0;
    }
    consume_frame_func_(
        consumed * playback_rate_,
#if SB_API_VERSION >= 12
        (SbTime)kSbTimeMax,  // Async audio frames reporting not supported
#endif // SB_API_VERSION >= 12
        context_);
  }
}

}  // namespace

SbAudioSink AlsaAudioSinkType::Create(
    int channels,
    int sampling_frequency_hz,
    SbMediaAudioSampleType audio_sample_type,
    SbMediaAudioFrameStorageType audio_frame_storage_type,
    SbAudioSinkFrameBuffers frame_buffers,
    int frames_per_channel,
    SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
    SbAudioSinkConsumeFramesFunc consume_frames_func,
    void* context) {
  AlsaAudioSink* audio_sink = new AlsaAudioSink(
      this, channels, sampling_frequency_hz, audio_sample_type, frame_buffers,
      frames_per_channel, update_source_status_func, consume_frames_func,
      context);
  if (!audio_sink->is_valid()) {
    delete audio_sink;
    return kSbAudioSinkInvalid;
  }

  return audio_sink;
}

}  // namespace alsa
}  // namespace shared
}  // namespace starboard

namespace {
SbAudioSinkPrivate::Type* alsa_audio_sink_type_;
}  // namespace

// static
void SbAudioSinkPrivate::PlatformInitialize() {
  SB_DCHECK(!alsa_audio_sink_type_);
  alsa_audio_sink_type_ = new starboard::shared::alsa::AlsaAudioSinkType;
  SetPrimaryType(alsa_audio_sink_type_);
  EnableFallbackToStub();
}

// static
void SbAudioSinkPrivate::PlatformTearDown() {
  SB_DCHECK(alsa_audio_sink_type_ == GetPrimaryType());
  SetPrimaryType(NULL);
  delete alsa_audio_sink_type_;
  alsa_audio_sink_type_ = NULL;
}
