// Copyright 2019 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/android/shared/audio_sink_min_required_frames_tester.h"

#include <vector>

#include "starboard/android/shared/audio_track_audio_sink_type.h"

namespace starboard {
namespace android {
namespace shared {

namespace {
const int kCheckpointFramesInterval = 1024;

// 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;
}
}  // namespace

MinRequiredFramesTester::MinRequiredFramesTester(int max_required_frames,
                                                 int required_frames_increment,
                                                 int min_stable_played_frames)
    : max_required_frames_(max_required_frames),
      required_frames_increment_(required_frames_increment),
      min_stable_played_frames_(min_stable_played_frames),
      condition_variable_(mutex_),
      destroying_(false) {}

MinRequiredFramesTester::~MinRequiredFramesTester() {
  SB_DCHECK(thread_checker_.CalledOnValidThread());
  destroying_.store(true);
  if (SbThreadIsValid(tester_thread_)) {
    {
      ScopedLock scoped_lock(mutex_);
      condition_variable_.Signal();
    }
    SbThreadJoin(tester_thread_, NULL);
    tester_thread_ = kSbThreadInvalid;
  }
}

void MinRequiredFramesTester::AddTest(
    int number_of_channels,
    SbMediaAudioSampleType sample_type,
    int sample_rate,
    const OnMinRequiredFramesReceivedCallback& received_cb,
    int default_required_frames) {
  SB_DCHECK(thread_checker_.CalledOnValidThread());
  // MinRequiredFramesTester doesn't support to add test after starts.
  SB_DCHECK(!SbThreadIsValid(tester_thread_));

  test_tasks_.emplace_back(number_of_channels, sample_type, sample_rate,
                           received_cb, default_required_frames);
}

void MinRequiredFramesTester::Start() {
  SB_DCHECK(thread_checker_.CalledOnValidThread());
  // MinRequiredFramesTester only supports to start once.
  SB_DCHECK(!SbThreadIsValid(tester_thread_));

  tester_thread_ =
      SbThreadCreate(0, kSbThreadPriorityLowest, kSbThreadNoAffinity, true,
                     "audio_track_tester",
                     &MinRequiredFramesTester::TesterThreadEntryPoint, this);
  SB_DCHECK(SbThreadIsValid(tester_thread_));
}

// static
void* MinRequiredFramesTester::TesterThreadEntryPoint(void* context) {
  SB_DCHECK(context);
  MinRequiredFramesTester* tester =
      static_cast<MinRequiredFramesTester*>(context);
  tester->TesterThreadFunc();
  return NULL;
}

void MinRequiredFramesTester::TesterThreadFunc() {
  bool wait_timeout = false;
  for (const TestTask& task : test_tasks_) {
    // Need to check |destroying_| before start, as MinRequiredFramesTester may
    // be destroyed immediately after tester thread started.
    if (destroying_.load()) {
      break;
    }
    std::vector<uint8_t> silence_buffer(max_required_frames_ *
                                            task.number_of_channels *
                                            GetSampleSize(task.sample_type),
                                        0);
    void* frame_buffers[1];
    frame_buffers[0] = silence_buffer.data();

    // Set default values.
    min_required_frames_ = task.default_required_frames;
    total_consumed_frames_ = 0;
    last_underrun_count_ = -1;
    last_total_consumed_frames_ = 0;

    audio_sink_ = new AudioTrackAudioSink(
        NULL, task.number_of_channels, task.sample_rate, task.sample_type,
        frame_buffers, max_required_frames_,
        min_required_frames_ * task.number_of_channels *
            GetSampleSize(task.sample_type),
        &MinRequiredFramesTester::UpdateSourceStatusFunc,
        &MinRequiredFramesTester::ConsumeFramesFunc, this);
    {
      ScopedLock scoped_lock(mutex_);
      wait_timeout = !condition_variable_.WaitTimed(kSbTimeSecond * 5);
    }

    if (wait_timeout) {
      SB_LOG(ERROR) << "Audio sink min required frames tester timeout.";
    }

    delete audio_sink_;
    audio_sink_ = nullptr;

    // Call |received_cb_| after audio sink thread is ended.
    // |min_required_frames_| is shared between two threads.
    if (!destroying_.load() && !wait_timeout) {
      task.received_cb(task.number_of_channels, task.sample_type,
                       task.sample_rate, min_required_frames_);
    }
  }
}

// static
void MinRequiredFramesTester::UpdateSourceStatusFunc(int* frames_in_buffer,
                                                     int* offset_in_frames,
                                                     bool* is_playing,
                                                     bool* is_eos_reached,
                                                     void* context) {
  MinRequiredFramesTester* tester =
      static_cast<MinRequiredFramesTester*>(context);
  SB_DCHECK(tester);
  SB_DCHECK(frames_in_buffer);
  SB_DCHECK(offset_in_frames);
  SB_DCHECK(is_playing);
  SB_DCHECK(is_eos_reached);

  tester->UpdateSourceStatus(frames_in_buffer, offset_in_frames, is_playing,
                             is_eos_reached);
}

// static
void MinRequiredFramesTester::ConsumeFramesFunc(int frames_consumed,
                                                SbTime frames_consumed_at,
                                                void* context) {
  MinRequiredFramesTester* tester =
      static_cast<MinRequiredFramesTester*>(context);
  SB_DCHECK(tester);

  tester->ConsumeFrames(frames_consumed);
}

void MinRequiredFramesTester::UpdateSourceStatus(int* frames_in_buffer,
                                                 int* offset_in_frames,
                                                 bool* is_playing,
                                                 bool* is_eos_reached) {
  *frames_in_buffer = min_required_frames_;
  *offset_in_frames = 0;
  *is_playing = true;
  *is_eos_reached = false;
}

void MinRequiredFramesTester::ConsumeFrames(int frames_consumed) {
  total_consumed_frames_ += frames_consumed;
  // Wait until played enough frames.
  if (total_consumed_frames_ - kCheckpointFramesInterval <
      last_total_consumed_frames_) {
    return;
  }
  if (last_underrun_count_ == -1) {
    // |last_underrun_count_| is unknown, record the current underrun count
    // and start to observe the underrun count.
    last_underrun_count_ = audio_sink_->GetUnderrunCount();
    last_total_consumed_frames_ = total_consumed_frames_;
    return;
  }
  // The playback should be played for a while. If we still get new underruns,
  // we need to write more buffers into audio sink.
  int underrun_count = audio_sink_->GetUnderrunCount();
  if (underrun_count > last_underrun_count_) {
    min_required_frames_ += required_frames_increment_;
    if (min_required_frames_ >= max_required_frames_) {
      SB_LOG(WARNING) << "Min required frames reached maximum.";
    } else {
      last_underrun_count_ = -1;
      last_total_consumed_frames_ = total_consumed_frames_;
      return;
    }
  }

  if (min_required_frames_ >= max_required_frames_ ||
      total_consumed_frames_ - min_stable_played_frames_ >=
          last_total_consumed_frames_) {
    // |min_required_frames_| reached maximum, or playback is stable and
    // doesn't have underruns. Stop the test.
    last_total_consumed_frames_ = INT_MAX;
    ScopedLock scoped_lock(mutex_);
    condition_variable_.Signal();
  }
}

}  // namespace shared
}  // namespace android
}  // namespace starboard
