// Copyright 2018 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/starboard/microphone/microphone_internal.h"

#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>

#include <algorithm>
#include <queue>

#include "starboard/android/shared/jni_env_ext.h"
#include "starboard/common/log.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/memory.h"
#include "starboard/shared/starboard/thread_checker.h"

using starboard::android::shared::JniEnvExt;

namespace starboard {
namespace android {
namespace shared {
namespace {

const int kSampleRateInHz = 16000;
const int kSampleRateInMillihertz = kSampleRateInHz * 1000;
const int kNumOfOpenSLESBuffers = 2;
const int kSamplesPerBuffer = 128;
const int kBufferSizeInBytes = kSamplesPerBuffer * sizeof(int16_t);

bool CheckReturnValue(SLresult result) {
  return result == SL_RESULT_SUCCESS;
}
}  // namespace

class SbMicrophoneImpl : public SbMicrophonePrivate {
 public:
  SbMicrophoneImpl();
  ~SbMicrophoneImpl() override;

  bool Open() override;
  bool Close() override;
  int Read(void* out_audio_data, int audio_data_size) override;

  void SetPermission(bool is_granted);
  static bool IsMicrophoneDisconnected();
  static bool IsMicrophoneMute();

 private:
  enum State { kWaitPermission, kPermissionGranted, kOpened, kClosed };

  static void SwapAndPublishBuffer(SLAndroidSimpleBufferQueueItf buffer_object,
                                   void* context);
  void SwapAndPublishBuffer();

  bool CreateAudioRecorder();
  void DeleteAudioRecorder();

  void ClearBuffer();

  bool RequestAudioPermission();
  bool StartRecording();
  bool StopRecording();

  SLObjectItf engine_object_;
  SLEngineItf engine_;
  SLObjectItf recorder_object_;
  SLRecordItf recorder_;
  SLAndroidSimpleBufferQueueItf buffer_object_;
  SLAndroidConfigurationItf config_object_;

  // Keeps track of the microphone's current state.
  State state_;
  // Audio data that has been delivered to the buffer queue.
  std::queue<int16_t*> delivered_queue_;
  // Audio data that is ready to be read.
  std::queue<int16_t*> ready_queue_;
};

SbMicrophoneImpl::SbMicrophoneImpl()
    : engine_object_(nullptr),
      engine_(nullptr),
      recorder_object_(nullptr),
      recorder_(nullptr),
      buffer_object_(nullptr),
      config_object_(nullptr),
      state_(kClosed) {}

SbMicrophoneImpl::~SbMicrophoneImpl() {
  Close();
}

bool SbMicrophoneImpl::RequestAudioPermission() {
  JniEnvExt* env = JniEnvExt::Get();
  jobject j_audio_permission_requester =
      static_cast<jobject>(env->CallStarboardObjectMethodOrAbort(
          "getAudioPermissionRequester",
          "()Ldev/cobalt/coat/AudioPermissionRequester;"));
  jboolean j_permission = env->CallBooleanMethodOrAbort(
      j_audio_permission_requester, "requestRecordAudioPermission", "(J)Z",
      reinterpret_cast<intptr_t>(this));
  return j_permission;
}

// static
bool SbMicrophoneImpl::IsMicrophoneDisconnected() {
  JniEnvExt* env = JniEnvExt::Get();
  jboolean j_microphone =
      env->CallStarboardBooleanMethodOrAbort("isMicrophoneDisconnected", "()Z");
  return j_microphone;
}

// static
bool SbMicrophoneImpl::IsMicrophoneMute() {
  JniEnvExt* env = JniEnvExt::Get();
  jboolean j_microphone =
      env->CallStarboardBooleanMethodOrAbort("isMicrophoneMute", "()Z");
  return j_microphone;
}

bool SbMicrophoneImpl::Open() {
  if (state_ == kOpened) {
    // The microphone has already been opened; clear the unread buffer. See
    // starboard/microphone.h for more info.
    ClearBuffer();
    return true;
  }

  if (IsMicrophoneDisconnected()) {
    SB_DLOG(WARNING) << "No microphone connected.";
    return false;
  } else if (!RequestAudioPermission()) {
    state_ = kWaitPermission;
    SB_DLOG(INFO) << "Waiting for audio permission.";
    // The permission is not set; this causes the MicrophoneManager to call
    // read() repeatedly and wait for the user's response.
    return true;
  } else if (!StartRecording()) {
    SB_DLOG(WARNING) << "Error starting recording.";
    return false;
  }

  // Successfully opened the microphone and started recording.
  state_ = kOpened;
  return true;
}

bool SbMicrophoneImpl::StartRecording() {
  if (!CreateAudioRecorder()) {
    SB_DLOG(WARNING) << "Create audio recorder failed.";
    DeleteAudioRecorder();
    return false;
  }

  // Enqueues kNumOfOpenSLESBuffers zero buffers to start.
  // Adds buffers to the queue before changing state to ensure that recording
  // starts as soon as the state is modified.
  for (int i = 0; i < kNumOfOpenSLESBuffers; ++i) {
    int16_t* buffer = new int16_t[kSamplesPerBuffer];
    SbMemorySet(buffer, 0, kBufferSizeInBytes);
    delivered_queue_.push(buffer);
    SLresult result =
        (*buffer_object_)->Enqueue(buffer_object_, buffer, kBufferSizeInBytes);
    if (!CheckReturnValue(result)) {
      SB_DLOG(WARNING) << "Error adding buffers to the queue.";
      return false;
    }
  }

  // Start the recording by setting the state to |SL_RECORDSTATE_RECORDING|.
  // When the object is in the SL_RECORDSTATE_RECORDING state, adding buffers
  // will implicitly start the recording process.
  SLresult result =
      (*recorder_)->SetRecordState(recorder_, SL_RECORDSTATE_RECORDING);
  if (!CheckReturnValue(result)) {
    return false;
  }

  return true;
}

bool SbMicrophoneImpl::Close() {
  if (state_ == kClosed) {
    // The microphone has already been closed.
    return true;
  }

  if (state_ == kOpened && !StopRecording()) {
    SB_DLOG(WARNING) << "Error closing the microphone.";
    return false;
  }

  // Successfully closed the microphone and stopped recording.
  state_ = kClosed;
  return true;
}

bool SbMicrophoneImpl::StopRecording() {
  // Stop recording by setting the record state to |SL_RECORDSTATE_STOPPED|.
  SLresult result =
      (*recorder_)->SetRecordState(recorder_, SL_RECORDSTATE_STOPPED);
  if (!CheckReturnValue(result)) {
    return false;
  }

  ClearBuffer();

  DeleteAudioRecorder();

  return true;
}

int SbMicrophoneImpl::Read(void* out_audio_data, int audio_data_size) {
  if (state_ == kClosed || IsMicrophoneMute()) {
    // No audio data is read from a stopped or muted microphone; return an
    // error.
    return -1;
  }

  if (!out_audio_data || audio_data_size == 0 || state_ == kWaitPermission) {
    // No data to be read.
    return 0;
  }

  if (state_ == kPermissionGranted) {
    if (StartRecording()) {
      state_ = kOpened;
    } else {
      // Could not start recording; return an error.
      state_ = kClosed;
      return -1;
    }
  }

  int read_bytes = 0;
  scoped_ptr<int16_t> buffer;
  // Go through the ready queue, reading and sending audio data.
  while (!ready_queue_.empty() &&
         audio_data_size - read_bytes >= kBufferSizeInBytes) {
    buffer.reset(ready_queue_.front());
    SbMemoryCopy(static_cast<uint8_t*>(out_audio_data) + read_bytes,
                 buffer.get(), kBufferSizeInBytes);
    ready_queue_.pop();
    read_bytes += kBufferSizeInBytes;
  }

  buffer.reset();
  return read_bytes;
}

void SbMicrophoneImpl::SetPermission(bool is_granted) {
  state_ = is_granted ? kPermissionGranted : kClosed;
}

// static
void SbMicrophoneImpl::SwapAndPublishBuffer(
    SLAndroidSimpleBufferQueueItf buffer_object,
    void* context) {
  SbMicrophoneImpl* recorder = static_cast<SbMicrophoneImpl*>(context);
  recorder->SwapAndPublishBuffer();
}

void SbMicrophoneImpl::SwapAndPublishBuffer() {
  if (!delivered_queue_.empty()) {
    // The front item in the delivered queue already has the buffered data, so
    // move it from the delivered queue to the ready queue for future reads.
    int16_t* buffer = delivered_queue_.front();
    delivered_queue_.pop();
    ready_queue_.push(buffer);
  }

  if (state_ == kOpened) {
    int16_t* buffer = new int16_t[kSamplesPerBuffer];
    SbMemorySet(buffer, 0, kBufferSizeInBytes);
    delivered_queue_.push(buffer);
    SLresult result =
        (*buffer_object_)->Enqueue(buffer_object_, buffer, kBufferSizeInBytes);
    CheckReturnValue(result);
  }
}

bool SbMicrophoneImpl::CreateAudioRecorder() {
  SLresult result;
  // Initializes the SL engine object with specific options.
  // OpenSL ES for Android is designed for multi-threaded applications and
  // is thread-safe.
  result = slCreateEngine(&engine_object_, 0, nullptr, 0, nullptr, nullptr);
  if (!CheckReturnValue(result)) {
    SB_DLOG(WARNING) << "Error creating the SL engine object.";
    return false;
  }

  // Realize the SL engine object in synchronous mode.
  result = (*engine_object_)
               ->Realize(engine_object_, /* async = */ SL_BOOLEAN_FALSE);
  if (!CheckReturnValue(result)) {
    SB_DLOG(WARNING) << "Error realizing the SL engine object.";
    return false;
  }

  // Get the SL engine interface.
  result =
      (*engine_object_)->GetInterface(engine_object_, SL_IID_ENGINE, &engine_);
  if (!CheckReturnValue(result)) {
    SB_DLOG(WARNING) << "Error getting the SL engine interface.";
    return false;
  }

  // Audio source configuration; the audio source is an I/O device data locator.
  SLDataLocator_IODevice input_dev_locator = {
      SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
      SL_DEFAULTDEVICEID_AUDIOINPUT, nullptr};

  SLDataSource audio_source = {&input_dev_locator, nullptr};
  SLDataLocator_AndroidSimpleBufferQueue simple_buffer_queue = {
      SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, kNumOfOpenSLESBuffers};

  // Audio sink configuration; the audio sink is a simple buffer queue. PCM is
  // the only data format allowed with buffer queues.
  SLAndroidDataFormat_PCM_EX format = {
      SL_ANDROID_DATAFORMAT_PCM_EX, 1 /* numChannels */,
      kSampleRateInMillihertz,      SL_PCMSAMPLEFORMAT_FIXED_16,
      SL_PCMSAMPLEFORMAT_FIXED_16,  SL_SPEAKER_FRONT_CENTER,
      SL_BYTEORDER_LITTLEENDIAN,    SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT};
  SLDataSink audio_sink = {&simple_buffer_queue, &format};

  const int kCount = 2;
  const SLInterfaceID kInterfaceId[kCount] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
                                              SL_IID_ANDROIDCONFIGURATION};
  const SLboolean kInterfaceRequired[kCount] = {SL_BOOLEAN_TRUE,
                                                SL_BOOLEAN_TRUE};
  // Create the audio recorder.
  result = (*engine_)->CreateAudioRecorder(engine_, &recorder_object_,
                                           &audio_source, &audio_sink, kCount,
                                           kInterfaceId, kInterfaceRequired);
  if (!CheckReturnValue(result)) {
    SB_DLOG(WARNING) << "Error creating the audio recorder.";
    return false;
  }

  // Configure the audio recorder (before it is realized); get the configuration
  // interface.
  result = (*recorder_object_)
               ->GetInterface(recorder_object_, SL_IID_ANDROIDCONFIGURATION,
                              &config_object_);
  if (!CheckReturnValue(result)) {
    SB_DLOG(WARNING) << "Error getting the audio recorder interface.";
    return false;
  }

  // Use the main microphone tuned for voice recognition.
  const SLuint32 kPresetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
  result =
      (*config_object_)
          ->SetConfiguration(config_object_, SL_ANDROID_KEY_RECORDING_PRESET,
                             &kPresetValue, sizeof(SLuint32));
  if (!CheckReturnValue(result)) {
    SB_DLOG(WARNING) << "Error configuring the audio recorder.";
    return false;
  }

  // Realize the recorder in synchronous mode.
  result = (*recorder_object_)
               ->Realize(recorder_object_, /* async = */ SL_BOOLEAN_FALSE);
  if (!CheckReturnValue(result)) {
    SB_DLOG(WARNING) << "Error realizing the audio recorder. Double check that "
                        "the microphone is connected to the device.";
    return false;
  }

  // Get the record interface (an implicit interface).
  result = (*recorder_object_)
               ->GetInterface(recorder_object_, SL_IID_RECORD, &recorder_);
  if (!CheckReturnValue(result)) {
    SB_DLOG(WARNING) << "Error getting the audio recorder interface.";
    return false;
  }

  // Get the buffer queue interface which was explicitly requested.
  result = (*recorder_object_)
               ->GetInterface(recorder_object_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
                              &buffer_object_);
  if (!CheckReturnValue(result)) {
    SB_DLOG(WARNING) << "Error getting the buffer queue interface.";
    return false;
  }

  // Setup to receive buffer queue event callbacks for when a buffer in the
  // queue is completed.
  result =
      (*buffer_object_)
          ->RegisterCallback(buffer_object_,
                             &SbMicrophoneImpl::SwapAndPublishBuffer, this);
  if (!CheckReturnValue(result)) {
    SB_DLOG(WARNING) << "Error registering buffer queue callbacks.";
    return false;
  }

  return true;
}

void SbMicrophoneImpl::DeleteAudioRecorder() {
  if (recorder_object_) {
    (*recorder_object_)->Destroy(recorder_object_);
  }

  config_object_ = nullptr;
  buffer_object_ = nullptr;
  recorder_ = nullptr;
  recorder_object_ = nullptr;

  // Destroy the engine object.
  if (engine_object_) {
    (*engine_object_)->Destroy(engine_object_);
  }
  engine_ = nullptr;
  engine_object_ = nullptr;
}

void SbMicrophoneImpl::ClearBuffer() {
  // Clear the buffer queue to get rid of old data.
  if (buffer_object_) {
    SLresult result = (*buffer_object_)->Clear(buffer_object_);
    if (!CheckReturnValue(result)) {
      SB_DLOG(WARNING) << "Error clearing the buffer.";
    }
  }

  while (!delivered_queue_.empty()) {
    delete[] delivered_queue_.front();
    delivered_queue_.pop();
  }

  while (!ready_queue_.empty()) {
    delete[] ready_queue_.front();
    ready_queue_.pop();
  }
}

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

int SbMicrophonePrivate::GetAvailableMicrophones(
    SbMicrophoneInfo* out_info_array,
    int info_array_size) {
  // Note that there is no way of checking for a connected microphone/device
  // before API 23, so GetAvailableMicrophones() will assume a microphone is
  // connected and always return 1 on APIs < 23.
  if (starboard::android::shared::SbMicrophoneImpl::
          IsMicrophoneDisconnected()) {
    SB_DLOG(WARNING) << "No microphone connected.";
    return 0;
  }
  if (starboard::android::shared::SbMicrophoneImpl::IsMicrophoneMute()) {
    SB_DLOG(WARNING) << "Microphone is muted.";
    return 0;
  }

  if (out_info_array && info_array_size > 0) {
    // Only support one microphone.
    out_info_array[0].id = reinterpret_cast<SbMicrophoneId>(1);
    out_info_array[0].type = kSbMicrophoneUnknown;
    out_info_array[0].max_sample_rate_hz =
        starboard::android::shared::kSampleRateInHz;
    out_info_array[0].min_read_size =
        starboard::android::shared::kSamplesPerBuffer;
  }

  return 1;
}

bool SbMicrophonePrivate::IsMicrophoneSampleRateSupported(
    SbMicrophoneId id,
    int sample_rate_in_hz) {
  if (!SbMicrophoneIdIsValid(id)) {
    return false;
  }

  return sample_rate_in_hz == starboard::android::shared::kSampleRateInHz;
}

namespace {
const int kUnusedBufferSize = 32 * 1024;
// Only a single microphone is supported.
SbMicrophone s_microphone = kSbMicrophoneInvalid;

}  // namespace

SbMicrophone SbMicrophonePrivate::CreateMicrophone(SbMicrophoneId id,
                                                   int sample_rate_in_hz,
                                                   int buffer_size_bytes) {
  if (!SbMicrophoneIdIsValid(id) ||
      !IsMicrophoneSampleRateSupported(id, sample_rate_in_hz) ||
      buffer_size_bytes > kUnusedBufferSize || buffer_size_bytes <= 0) {
    return kSbMicrophoneInvalid;
  }

  if (s_microphone != kSbMicrophoneInvalid) {
    return kSbMicrophoneInvalid;
  }

  s_microphone = new starboard::android::shared::SbMicrophoneImpl();
  return s_microphone;
}

void SbMicrophonePrivate::DestroyMicrophone(SbMicrophone microphone) {
  if (!SbMicrophoneIsValid(microphone)) {
    return;
  }

  SB_DCHECK(s_microphone == microphone);
  s_microphone->Close();

  delete s_microphone;
  s_microphone = kSbMicrophoneInvalid;
}

extern "C" SB_EXPORT_PLATFORM void
Java_dev_cobalt_coat_AudioPermissionRequester_nativeHandlePermission(
    JNIEnv* env,
    jobject unused_this,
    jlong nativeSbMicrophoneImpl,
    jboolean is_granted) {
  starboard::android::shared::SbMicrophoneImpl* native =
      reinterpret_cast<starboard::android::shared::SbMicrophoneImpl*>(
          nativeSbMicrophoneImpl);
  native->SetPermission(is_granted);
}
