// 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(SbTime seek_to_time) {
  SB_DCHECK(BelongsToCurrentThread());
  SB_DCHECK(seek_to_time >= 0);
  {
    ScopedLock lock(mutex_);
    seeking_to_time_ = std::max<SbTime>(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();
}

SbTime 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;
  SbTime sink_playback_time = static_cast<SbTime>(
      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_;
  }

  SbTime 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();
  SbTime process_audio_buffers_job_delay = 5 * kSbTimeMillisecond;

  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 = 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);
    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_ / kSbTimeSecond;
  // 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 * kSbTimeMillisecond);
}

SbTime 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 SbTime.
  return ((current_time_converted - update_time) * 100) /
         kSbTimeNanosecondsPerMicrosecond;
}

SbTime AudioRendererPassthrough::CalculateLastOutputTime(
    scoped_refptr<DecodedAudio>& decoded_audio) {
  return decoded_audio->timestamp() +
         (decoded_audio->frames() / iec_sample_rate_ * kSbTimeSecond);
}

}  // namespace uwp
}  // namespace shared
}  // namespace starboard
