// Copyright 2017 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/win32/audio_decoder_thread.h"

#include <deque>
#include <vector>

namespace starboard {
namespace shared {
namespace win32 {
namespace {

// Size of the queue for audio units.
const size_t kMaxProcessingElements = 64;

size_t WriteAsMuchAsPossible(
    std::deque<scoped_refptr<InputBuffer> >* data_queue,
    AbstractWin32AudioDecoder* audio_decoder) {
  const size_t original_size = data_queue->size();
  while (!data_queue->empty()) {
    scoped_refptr<InputBuffer> buff = data_queue->front();
    data_queue->pop_front();

    if (buff) {
      if (!audio_decoder->TryWrite(buff)) {
        data_queue->push_front(buff);
        break;
      }
    } else {
      audio_decoder->WriteEndOfStream();
    }
  }
  return original_size - data_queue->size();
}

std::vector<DecodedAudioPtr> ReadAllDecodedAudioSamples(
    AbstractWin32AudioDecoder* audio_decoder) {
  std::vector<DecodedAudioPtr> decoded_audio_out;
  while (DecodedAudioPtr decoded_datum = audio_decoder->ProcessAndRead()) {
    decoded_audio_out.push_back(decoded_datum);
  }
  return decoded_audio_out;
}

}  // namespace.

AudioDecoderThread::AudioDecoderThread(AbstractWin32AudioDecoder* decoder_impl,
                                       AudioDecodedCallback* callback)
    : Thread("AudioDecoderThd"),
      win32_audio_decoder_(decoder_impl),
      callback_(callback) {
  Start();
}

AudioDecoderThread::~AudioDecoderThread() {
  Join();
}

bool AudioDecoderThread::QueueInput(const scoped_refptr<InputBuffer>& buffer) {
  {
    ::starboard::ScopedLock lock(input_buffer_queue_mutex_);
    input_buffer_queue_.push_back(buffer);
  }

  // increment() returns the previous value.
  size_t element_count = processing_elements_.increment() + 1;
  semaphore_.Put();
  return element_count < kMaxProcessingElements;
}

void AudioDecoderThread::QueueEndOfStream() {
  scoped_refptr<InputBuffer> empty;
  QueueInput(empty);
}

void AudioDecoderThread::Run() {
  std::deque<scoped_refptr<InputBuffer> > local_queue;

  while (!join_called()) {
    if (local_queue.empty()) {
      TransferPendingInputTo(&local_queue);
    }
    bool work_done = false;
    size_t number_written =
        WriteAsMuchAsPossible(&local_queue, win32_audio_decoder_);
    if (number_written > 0) {
      processing_elements_.fetch_sub(static_cast<int32_t>(number_written));
      work_done = true;
    }

    std::vector<DecodedAudioPtr> decoded_audio =
        ReadAllDecodedAudioSamples(win32_audio_decoder_);

    if (!decoded_audio.empty()) {
      work_done = true;
      for (auto it = decoded_audio.begin(); it != decoded_audio.end(); ++it) {
        callback_->OnAudioDecoded(*it);
      }
    }

    if (!work_done) {
      semaphore_.TakeWait(kSbTimeMillisecond);
    }
  }
}

void AudioDecoderThread::TransferPendingInputTo(
    std::deque<scoped_refptr<InputBuffer> >* destination) {
  ::starboard::ScopedLock lock(input_buffer_queue_mutex_);
  while (!input_buffer_queue_.empty()) {
    destination->push_back(input_buffer_queue_.front());
    input_buffer_queue_.pop_front();
  }
}

}  // namespace win32
}  // namespace shared
}  // namespace starboard
