// Copyright 2022 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/uwp/audio_renderer_passthrough.h"

#include <algorithm>
#include <string>

#include "starboard/common/log.h"
#include "starboard/common/string.h"

namespace starboard {
namespace shared {
namespace uwp {

namespace {

int CodecToIecSampleRate(SbMediaAudioCodec codec) {
  switch (codec) {
    case kSbMediaAudioCodecAc3:
      return 48000;
    case kSbMediaAudioCodecEac3:
      return 192000;
    default:
      SB_NOTREACHED();
      return 0;
  }
}

}  // namespace

AudioRendererPassthrough::AudioRendererPassthrough(
    scoped_ptr<AudioDecoder> audio_decoder,
    const AudioStreamInfo& audio_stream_info)
    : channels_(audio_stream_info.number_of_channels),
      codec_(audio_stream_info.codec),
      iec_sample_rate_(CodecToIecSampleRate(audio_stream_info.codec)),
      decoder_(audio_decoder.Pass()),
      sink_(new WASAPIAudioSink),
      process_audio_buffers_job_(
          std::bind(&AudioRendererPassthrough::ProcessAudioBuffers, this)) {
  SB_DCHECK(codec_ == kSbMediaAudioCodecAc3 ||
            codec_ == kSbMediaAudioCodecEac3);
  SB_DCHECK(decoder_);
  QueryPerformanceFrequency(&performance_frequency_);
  SB_DCHECK(performance_frequency_.QuadPart > 0);
  SB_LOG(INFO) << "Creating AudioRendererPassthrough with " << channels_
               << " channels.";
}

AudioRendererPassthrough::~AudioRendererPassthrough() {
  SB_DCHECK(BelongsToCurrentThread());
  SB_LOG(INFO) << "Destroying AudioRendererPassthrough with " << channels_
               << " channels.";
}

void AudioRendererPassthrough::Initialize(const ErrorCB& error_cb,
                                          const PrerolledCB& prerolled_cb,
                                          const EndedCB& ended_cb) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(error_cb);
  SB_DCHECK(prerolled_cb);
  SB_DCHECK(ended_cb);
  SB_DCHECK(!error_cb_);
  SB_DCHECK(!prerolled_cb_);
  SB_DCHECK(!ended_cb_);

  error_cb_ = error_cb;
  prerolled_cb_ = prerolled_cb;
  ended_cb_ = ended_cb;

  decoder_->Initialize(
      std::bind(&AudioRendererPassthrough::OnDecoderOutput, this), error_cb);

  if (!sink_->Initialize(channels_, iec_sample_rate_, codec_)) {
    error_cb_(kSbPlayerErrorDecode, "failed to start audio sink");
  }
}

void AudioRendererPassthrough::WriteSamples(const InputBuffers& input_buffers) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(input_buffers.size() == 1);
  SB_DCHECK(input_buffers[0]);
  SB_DCHECK(can_accept_more_data_.load());

  if (end_of_stream_written_.load()) {
    SB_LOG(ERROR) << "Appending audio sample at "
                  << input_buffers[0]->timestamp() << " after EOS reached.";
    return;
  }

  can_accept_more_data_.store(false);
  decoder_->Decode(
      input_buffers,
      std::bind(&AudioRendererPassthrough::OnDecoderConsumed, this));
}

void AudioRendererPassthrough::WriteEndOfStream() {
  SB_DCHECK(BelongsToCurrentThread());

  if (end_of_stream_written_.load()) {
    SB_LOG(ERROR) << "Try to write EOS after EOS is reached";
    return;
  }

  end_of_stream_written_.store(true);
  decoder_->WriteEndOfStream();
}

void AudioRendererPassthrough::SetVolume(double volume) {
  SB_DCHECK(BelongsToCurrentThread());
  sink_->SetVolume(volume);
}

bool AudioRendererPassthrough::IsEndOfStreamWritten() const {
  SB_DCHECK(BelongsToCurrentThread());

  return end_of_stream_written_.load();
}

bool AudioRendererPassthrough::IsEndOfStreamPlayed() const {
  SB_DCHECK(BelongsToCurrentThread());

  return end_of_stream_played_.load();
}

bool AudioRendererPassthrough::CanAcceptMoreData() const {
  SB_DCHECK(BelongsToCurrentThread());

  return !end_of_stream_written_.load() &&
         pending_inputs_.size() < kMaxDecodedAudios &&
         can_accept_more_data_.load();
}

void AudioRendererPassthrough::Play() {
  SB_DCHECK(BelongsToCurrentThread());
  ScopedLock lock(mutex_);
  paused_ = false;
  sink_->Play();
}

void AudioRendererPassthrough::Pause() {
  SB_DCHECK(BelongsToCurrentThread());
  ScopedLock lock(mutex_);
  paused_ = true;
  sink_->Pause();
}

void AudioRendererPassthrough::SetPlaybackRate(double playback_rate) {
  SB_DCHECK(BelongsToCurrentThread());

  if (playback_rate > 0.0 && playback_rate != 1.0) {
    std::string error_message = ::starboard::FormatString(
        "Playback rate %f is not supported", playback_rate);
    error_cb_(kSbPlayerErrorDecode, error_message);
    return;
  }

  ScopedLock lock(mutex_);
  playback_rate_ = playback_rate;
  sink_->SetPlaybackRate(playback_rate);
}

void AudioRendererPassthrough::Seek(int64_t seek_to_time) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(seek_to_time >= 0);
  {
    ScopedLock lock(mutex_);
    seeking_to_time_ = std::max<int64_t>(seek_to_time, 0);
    seeking_ = true;
  }

  total_frames_sent_to_sink_ = 0;
  can_accept_more_data_.store(true);
  process_audio_buffers_job_token_.ResetToInvalid();
  total_buffers_sent_to_sink_ = 0;
  end_of_stream_written_.store(false);
  end_of_stream_played_.store(false);
  pending_inputs_ = std::queue<scoped_refptr<DecodedAudio>>();
  sink_->Reset();
  decoder_->Reset();

  CancelPendingJobs();
}

int64_t AudioRendererPassthrough::GetCurrentMediaTime(bool* is_playing,
                                                      bool* is_eos_played,
                                                      bool* is_underflow,
                                                      double* playback_rate) {
  SB_DCHECK(is_playing);
  SB_DCHECK(is_eos_played);
  SB_DCHECK(is_underflow);
  SB_DCHECK(playback_rate);

  ScopedLock lock(mutex_);
  *is_playing = !paused_ && !seeking_;
  *is_eos_played = end_of_stream_played_.load();
  *is_underflow = false;  // TODO: Support underflow
  *playback_rate = playback_rate_;

  if (seeking_) {
    return seeking_to_time_;
  }

  uint64_t sink_playback_time_updated_at;
  int64_t sink_playback_time = static_cast<int64_t>(
      sink_->GetCurrentPlaybackTime(&sink_playback_time_updated_at));
  if (sink_playback_time <= 0) {
    if (sink_playback_time < 0) {
      error_cb_(kSbPlayerErrorDecode,
                "Error obtaining playback time from WASAPI sink");
    }
    return seeking_to_time_;
  }

  int64_t media_time = seeking_to_time_ + sink_playback_time;
  if (!sink_->playing()) {
    return media_time;
  }

  return media_time +
         CalculateElapsedPlaybackTime(sink_playback_time_updated_at);
}

void AudioRendererPassthrough::OnDecoderConsumed() {
  SB_DCHECK(BelongsToCurrentThread());
  can_accept_more_data_.store(true);
}

void AudioRendererPassthrough::OnDecoderOutput() {
  SB_DCHECK(BelongsToCurrentThread());
  int samples_per_second = 0;
  scoped_refptr<DecodedAudio> decoded_audio =
      decoder_->Read(&samples_per_second);
  SB_DCHECK(decoded_audio);
  pending_inputs_.push(decoded_audio);

  if (process_audio_buffers_job_token_.is_valid()) {
    RemoveJobByToken(process_audio_buffers_job_token_);
    process_audio_buffers_job_token_.ResetToInvalid();
  }
  ProcessAudioBuffers();
}

void AudioRendererPassthrough::ProcessAudioBuffers() {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(!pending_inputs_.empty());

  process_audio_buffers_job_token_.ResetToInvalid();
  int64_t process_audio_buffers_job_delay_usec = 5'000;  // 5ms

  scoped_refptr<DecodedAudio> decoded_audio = pending_inputs_.front();
  SB_DCHECK(decoded_audio);

  if (decoded_audio->is_end_of_stream()) {
    SB_DCHECK(end_of_stream_written_.load());
    ScopedLock lock(mutex_);
    if (seeking_) {
      seeking_ = false;
      Schedule(prerolled_cb_);
    }
    pending_inputs_.pop();
    SB_DCHECK(pending_inputs_.empty());
  } else {
    ScopedLock lock(mutex_);
    while (seeking_ && decoded_audio &&
           CalculateLastOutputTime(decoded_audio) < seeking_to_time_) {
      pending_inputs_.pop();
      decoded_audio = pending_inputs_.empty() ? scoped_refptr<DecodedAudio>()
                                              : pending_inputs_.front();
    }

    if (decoded_audio && TryToWriteAudioBufferToSink(decoded_audio)) {
      pending_inputs_.pop();
      process_audio_buffers_job_delay_usec = 0;
      if (seeking_ && total_buffers_sent_to_sink_ >= kNumPrerollDecodedAudios) {
        seeking_ = false;
        Schedule(prerolled_cb_);
      }
    }
  }

  if (!pending_inputs_.empty()) {
    process_audio_buffers_job_token_ = Schedule(
        process_audio_buffers_job_, process_audio_buffers_job_delay_usec);
    return;
  }

  if (end_of_stream_written_.load() && !end_of_stream_played_.load()) {
    TryToEndStream();
  }
}

bool AudioRendererPassthrough::TryToWriteAudioBufferToSink(
    scoped_refptr<DecodedAudio> decoded_audio) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(decoded_audio);

  bool buffer_written = sink_->WriteBuffer(decoded_audio);
  if (buffer_written && !decoded_audio->is_end_of_stream()) {
    total_frames_sent_to_sink_ += decoded_audio->frames();
    total_buffers_sent_to_sink_++;
  }
  return buffer_written;
}

void AudioRendererPassthrough::TryToEndStream() {
  bool is_playing, is_eos_played, is_underflow;
  double playback_rate;
  int64_t total_frames_played_by_sink =
      GetCurrentMediaTime(&is_playing, &is_eos_played, &is_underflow,
                          &playback_rate) *
      iec_sample_rate_ / 1'000'000;
  // Wait for the audio sink to output the remaining frames before calling
  // Pause().
  if (total_frames_played_by_sink >= total_frames_sent_to_sink_) {
    sink_->Pause();
    end_of_stream_played_.store(true);
    ended_cb_();
    return;
  }
  Schedule(std::bind(&AudioRendererPassthrough::TryToEndStream, this), 5'000);
}

int64_t AudioRendererPassthrough::CalculateElapsedPlaybackTime(
    uint64_t update_time) {
  LARGE_INTEGER current_time;
  QueryPerformanceCounter(&current_time);
  // Convert current performance counter timestamp to units of 100 nanoseconds.
  // https://docs.microsoft.com/en-us/windows/win32/api/audioclient/nf-audioclient-iaudioclock-getposition#remarks
  uint64_t current_time_converted =
      static_cast<double>(current_time.QuadPart) *
      (10000000.0 / static_cast<double>(performance_frequency_.QuadPart));
  SB_DCHECK(current_time_converted >= update_time);

  // Convert elapsed time to microseconds.
  return ((current_time_converted - update_time) * 100) / 1000;
}

int64_t AudioRendererPassthrough::CalculateLastOutputTime(
    scoped_refptr<DecodedAudio>& decoded_audio) {
  return decoded_audio->timestamp() +
         (decoded_audio->frames() / iec_sample_rate_ * 1'000'000);
}

}  // namespace uwp
}  // namespace shared
}  // namespace starboard
