// Copyright 2016 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/nplb/audio_sink_helpers.h"

#include <algorithm>

#include "starboard/common/log.h"
#include "starboard/configuration_constants.h"

namespace starboard {
namespace nplb {

namespace {

SbMediaAudioSampleType GetAnySupportedSampleType() {
  if (SbAudioSinkIsAudioSampleTypeSupported(
          kSbMediaAudioSampleTypeInt16Deprecated)) {
    return kSbMediaAudioSampleTypeInt16Deprecated;
  }
  return kSbMediaAudioSampleTypeFloat32;
}

SbMediaAudioFrameStorageType GetAnySupportedFrameStorageType() {
  if (SbAudioSinkIsAudioFrameStorageTypeSupported(
          kSbMediaAudioFrameStorageTypeInterleaved)) {
    return kSbMediaAudioFrameStorageTypeInterleaved;
  }
  return kSbMediaAudioFrameStorageTypePlanar;
}

}  // namespace

AudioSinkTestFrameBuffers::AudioSinkTestFrameBuffers(int channels)
    : channels_(channels),
      sample_type_(GetAnySupportedSampleType()),
      storage_type_(GetAnySupportedFrameStorageType()) {
  Init();
}

AudioSinkTestFrameBuffers::AudioSinkTestFrameBuffers(
    int channels,
    SbMediaAudioSampleType sample_type)
    : channels_(channels),
      sample_type_(sample_type),
      storage_type_(GetAnySupportedFrameStorageType()) {
  Init();
}

AudioSinkTestFrameBuffers::AudioSinkTestFrameBuffers(
    int channels,
    SbMediaAudioFrameStorageType storage_type)
    : channels_(channels),
      sample_type_(GetAnySupportedSampleType()),
      storage_type_(storage_type) {
  Init();
}

AudioSinkTestFrameBuffers::AudioSinkTestFrameBuffers(
    int channels,
    SbMediaAudioSampleType sample_type,
    SbMediaAudioFrameStorageType storage_type)
    : channels_(channels),
      sample_type_(sample_type),
      storage_type_(storage_type) {
  Init();
}

void AudioSinkTestFrameBuffers::Init() {
  if (storage_type_ == kSbMediaAudioFrameStorageTypeInterleaved) {
    frame_buffer_.resize(bytes_per_frame() * channels_ * kFramesPerChannel);
    frame_buffers_.resize(1);
    frame_buffers_[0] = &frame_buffer_[0];
  } else {
    // We make all planar audio channels share the same frame buffer.
    frame_buffer_.resize(bytes_per_frame() * frames_per_channel());
    frame_buffers_.resize(channels_, &frame_buffer_[0]);
  }
}

AudioSinkTestEnvironment::AudioSinkTestEnvironment(
    const AudioSinkTestFrameBuffers& frame_buffers)
    : frame_buffers_(frame_buffers), condition_variable_(mutex_) {
  sink_ = SbAudioSinkCreate(
      frame_buffers_.channels(), sample_rate(), frame_buffers_.sample_type(),
      frame_buffers_.storage_type(), frame_buffers_.frame_buffers(),
      frame_buffers_.frames_per_channel(), UpdateSourceStatusFunc,
      ConsumeFramesFunc, this);
}

AudioSinkTestEnvironment::~AudioSinkTestEnvironment() {
  SbAudioSinkDestroy(sink_);
}

void AudioSinkTestEnvironment::SetIsPlaying(bool is_playing) {
  ScopedLock lock(mutex_);
  is_playing_ = is_playing;
}

void AudioSinkTestEnvironment::AppendFrame(int frames_to_append) {
  ScopedLock lock(mutex_);
  AppendFrame_Locked(frames_to_append);
}

int AudioSinkTestEnvironment::GetFrameBufferFreeSpaceInFrames() const {
  ScopedLock lock(mutex_);
  return GetFrameBufferFreeSpaceInFrames_Locked();
}

bool AudioSinkTestEnvironment::WaitUntilUpdateStatusCalled() {
  ScopedLock lock(mutex_);
  int update_source_status_call_count = update_source_status_call_count_;
  SbTimeMonotonic start = SbTimeGetMonotonicNow();
  while (update_source_status_call_count == update_source_status_call_count_) {
    SbTime time_elapsed = SbTimeGetMonotonicNow() - start;
    if (time_elapsed >= kTimeToTry) {
      return false;
    }
    SbTime time_to_wait = kTimeToTry - time_elapsed;
    condition_variable_.WaitTimed(time_to_wait);
  }
  return true;
}

bool AudioSinkTestEnvironment::WaitUntilSomeFramesAreConsumed() {
  ScopedLock lock(mutex_);
  int frames_consumed = frames_consumed_;
  SbTimeMonotonic start = SbTimeGetMonotonicNow();
  while (frames_consumed == frames_consumed_) {
    SbTime time_elapsed = SbTimeGetMonotonicNow() - start;
    if (time_elapsed >= kTimeToTry) {
      return false;
    }
    SbTime time_to_wait = kTimeToTry - time_elapsed;
    condition_variable_.WaitTimed(time_to_wait);
  }
  return true;
}

bool AudioSinkTestEnvironment::WaitUntilAllFramesAreConsumed() {
  const int kMaximumFramesPerAppend = 1024;

  ScopedLock lock(mutex_);
  is_eos_reached_ = true;
  int frames_appended_before_eos = frames_appended_;
  SbTimeMonotonic start = SbTimeGetMonotonicNow();
  int silence_frames_appended = 0;

  while (frames_consumed_ < frames_appended_before_eos) {
    SbTime time_elapsed = SbTimeGetMonotonicNow() - start;
    if (time_elapsed >= kTimeToTry) {
      return false;
    }
    SbTime time_to_wait = kTimeToTry - time_elapsed;

    // Append silence as some audio sink implementations won't be able to finish
    // playback to the last frames filled.
    int silence_frames_to_append =
        std::min({GetFrameBufferFreeSpaceInFrames_Locked(),
                  frame_buffers_.frames_per_channel() - silence_frames_appended,
                  kMaximumFramesPerAppend});
    AppendFrame_Locked(silence_frames_to_append);
    silence_frames_appended += silence_frames_to_append;

    condition_variable_.WaitTimed(time_to_wait);
  }
  return true;
}

void AudioSinkTestEnvironment::AppendFrame_Locked(int frames_to_append) {
  mutex_.DCheckAcquired();

  frames_appended_ += frames_to_append;
}

int AudioSinkTestEnvironment::GetFrameBufferFreeSpaceInFrames_Locked() const {
  mutex_.DCheckAcquired();

  int frames_in_buffer = frames_appended_ - frames_consumed_;
  return frame_buffers_.frames_per_channel() - frames_in_buffer;
}

void AudioSinkTestEnvironment::OnUpdateSourceStatus(int* frames_in_buffer,
                                                    int* offset_in_frames,
                                                    bool* is_playing,
                                                    bool* is_eos_reached) {
  ScopedLock lock(mutex_);
  *frames_in_buffer = frames_appended_ - frames_consumed_;
  *offset_in_frames = frames_consumed_ % frame_buffers_.frames_per_channel();
  *is_playing = is_playing_;
  *is_eos_reached = is_eos_reached_;
  ++update_source_status_call_count_;
  condition_variable_.Signal();
}

void AudioSinkTestEnvironment::OnConsumeFrames(
    int frames_consumed
#if SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION || \
    SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)
    ,
    SbTime frames_consumed_at
#endif  // SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION ||
        // SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)
    ) {
#if SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION || \
    SB_HAS(SB_HAS_ASYNC_AUDIO_FRAMES_REPORTING)
  if (kSbHasAsyncAudioFramesReporting) {
    SB_DCHECK(frames_consumed_at <= SbTimeGetMonotonicNow());
  }
#endif  // SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION ||
        // SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)
  ScopedLock lock(mutex_);
  frames_consumed_ += frames_consumed;
  condition_variable_.Signal();
}

// static
void AudioSinkTestEnvironment::UpdateSourceStatusFunc(int* frames_in_buffer,
                                                      int* offset_in_frames,
                                                      bool* is_playing,
                                                      bool* is_eos_reached,
                                                      void* context) {
  AudioSinkTestEnvironment* environment =
      reinterpret_cast<AudioSinkTestEnvironment*>(context);
  environment->OnUpdateSourceStatus(frames_in_buffer, offset_in_frames,
                                    is_playing, is_eos_reached);
}

// static
void AudioSinkTestEnvironment::ConsumeFramesFunc(
    int frames_consumed,
#if SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION || \
    SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)
    SbTime frames_consumed_at,
#endif  // SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION ||
        // SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)
    void* context) {
  AudioSinkTestEnvironment* environment =
      reinterpret_cast<AudioSinkTestEnvironment*>(context);
#if SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION || \
    SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)
#if SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION
  if (!kSbHasAsyncAudioFramesReporting)
    frames_consumed_at = (SbTime)kSbTimeMax;
#endif
  environment->OnConsumeFrames(frames_consumed, frames_consumed_at);
#else   // SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION ||
        // SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)
  environment->OnConsumeFrames(frames_consumed);
#endif  // SB_API_VERSION >= SB_FEATURE_RUNTIME_CONFIGS_VERSION ||
        // SB_HAS(ASYNC_AUDIO_FRAMES_REPORTING)
}

}  // namespace nplb
}  // namespace starboard
