// Copyright 2017 Google Inc. 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"

// Windows headers.
#include <collection.h>
#include <MemoryBuffer.h>
#include <ppltasks.h>

// C++ headers.
#include <algorithm>
#include <deque>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

#include "starboard/atomic.h"
#include "starboard/common/semaphore.h"
#include "starboard/log.h"
#include "starboard/mutex.h"
#include "starboard/shared/uwp/app_accessors.h"
#include "starboard/shared/uwp/application_uwp.h"
#include "starboard/shared/uwp/async_utils.h"
#include "starboard/shared/win32/error_utils.h"
#include "starboard/shared/win32/simple_thread.h"
#include "starboard/shared/win32/wchar_utils.h"
#include "starboard/string.h"
#include "starboard/time.h"
#include "starboard/user.h"

#if !SB_HAS(MICROPHONE)
#error Microphone expected to be enabled when compiling a microphone impl.
#endif

using concurrency::task_continuation_context;
using Microsoft::WRL::ComPtr;
using starboard::Mutex;
using starboard::scoped_ptr;
using starboard::ScopedLock;
using starboard::Semaphore;
using starboard::shared::uwp::ApplicationUwp;
using starboard::shared::win32::CheckResult;
using starboard::shared::win32::platformStringToString;
using starboard::shared::win32::SimpleThread;
using Windows::Devices::Enumeration::DeviceInformation;
using Windows::Devices::Enumeration::DeviceInformationCollection;
using Windows::Foundation::EventRegistrationToken;
using Windows::Foundation::IMemoryBufferByteAccess;
using Windows::Foundation::IMemoryBufferReference;
using Windows::Foundation::TypedEventHandler;
using Windows::Media::Audio::AudioDeviceInputNode;
using Windows::Media::Audio::AudioDeviceNodeCreationStatus;
using Windows::Media::Audio::AudioFrameOutputNode;
using Windows::Media::Audio::AudioGraph;
using Windows::Media::Audio::AudioGraphCreationStatus;
using Windows::Media::Audio::AudioGraphSettings;
using Windows::Media::Audio::CreateAudioDeviceInputNodeResult;
using Windows::Media::Audio::CreateAudioGraphResult;
using Windows::Media::Audio::QuantumSizeSelectionMode;
using Windows::Media::AudioBuffer;
using Windows::Media::AudioBufferAccessMode;
using Windows::Media::AudioFrame;
using Windows::Media::Capture::MediaCategory;
using Windows::Media::Devices::MediaDevice;
using Windows::Media::MediaProperties::AudioEncodingProperties;
using Windows::Media::Render::AudioRenderCategory;

namespace {

// It appears that cobalt will only request 16khz.
const int kMinSampleRate = 16000;
const int kMaxSampleRate = 44100;
const int kNumChannels = 1;
const int kOutputBytesPerSample = sizeof(int16_t);
const int kMinReadSizeBytes = 4096;
const int kMicGain = 1;

// Controls the amount of time that a microphone will record muted audio
// before it signals a read error. Without this trigger, the app
// will continuously wait for audio data. This happens with the Kinect
// device, which when disconnected will still record 0-value samples.
const SbTime kTimeMutedThreshold = 3 * kSbTimeSecond;

// Maps [-1.0f, 1.0f] -> [-32768, 32767]
// Values outside of [-1.0f, 1.0] are clamped.
int16_t To16BitPcm(float val) {
  static const float kMaxFloatValue = std::numeric_limits<int16_t>::max();
  static const float kLowFloatValue = std::numeric_limits<int16_t>::lowest();
  if (val == 0.0f) {
    return 0;
  } else if (val > 0.0f) {
    if (val > 1.0f) {
      val = 1.0;
    }
    return static_cast<int16_t>(val * kMaxFloatValue);
  } else {
    if (val < -1.0f) {
      val = -1.0;
    }
    return static_cast<int16_t>(-1.0f * val * kLowFloatValue);
  }
}

const char* ToString(AudioDeviceNodeCreationStatus status) {
  switch (status) {
    case AudioDeviceNodeCreationStatus::AccessDenied:
      return "AccessDenied";
    case AudioDeviceNodeCreationStatus::DeviceNotAvailable:
      return "DeviceNotAvailable";
    case AudioDeviceNodeCreationStatus::FormatNotSupported:
      return "FormatNotSupported";
    case AudioDeviceNodeCreationStatus::Success:
      return "Success";
    case AudioDeviceNodeCreationStatus::UnknownFailure:
      return "UnknownFailure";
  }
  return "Unknown";
}

bool IsUiThread() {
  auto dispatcher = starboard::shared::uwp::GetDispatcher();
  // Is UI thread.
  return dispatcher->HasThreadAccess;
}

std::vector<DeviceInformation^> GetAllMicrophoneDevices() {
  std::vector<DeviceInformation^> output;
  Platform::String^ audio_str = MediaDevice::GetAudioCaptureSelector();
  DeviceInformationCollection^ all_devices =
      starboard::shared::uwp::WaitForResult(
          DeviceInformation::FindAllAsync(audio_str));
  for (DeviceInformation^ dev_info : all_devices) {
    output.push_back(dev_info);
  }

  return output;
}

AudioGraph^ CreateAudioGraph(AudioRenderCategory category,
                             QuantumSizeSelectionMode selection_mode) {
  AudioGraphSettings^ settings = ref new AudioGraphSettings(category);
  settings->QuantumSizeSelectionMode = selection_mode;
  CreateAudioGraphResult^ result =
      starboard::shared::uwp::WaitForResult(AudioGraph::CreateAsync(settings));
  SB_DCHECK(result->Status == AudioGraphCreationStatus::Success);
  AudioGraph^ graph = result->Graph;
  return graph;
}

std::vector<AudioDeviceInputNode^> GenerateAudioInputNodes(
    const std::vector<DeviceInformation^>& microphone_devices,
    AudioEncodingProperties^ encoding_properties,
    AudioGraph^ graph) {
  std::vector<AudioDeviceInputNode^> output;
  for (DeviceInformation^ mic : microphone_devices) {
    auto create_microphone_input_task = graph->CreateDeviceInputNodeAsync(
        MediaCategory::Speech, encoding_properties, mic);
    CreateAudioDeviceInputNodeResult^ deviceInputNodeResult =
        starboard::shared::uwp::WaitForResult(create_microphone_input_task);

    auto status = deviceInputNodeResult->Status;
    AudioDeviceInputNode^ input_node = deviceInputNodeResult->DeviceInputNode;

    if (status != AudioDeviceNodeCreationStatus::Success) {
      SB_LOG(INFO) << "Failed to create microphone with device name \""
                   << platformStringToString(mic->Name) << "\" because "
                   << ToString(status);
      continue;
    }

    SB_LOG(INFO) << "Created a microphone with device \""
                 << platformStringToString(mic->Name) << "\"";

    input_node->ConsumeInput = true;
    input_node->OutgoingGain = kMicGain;
    output.push_back(input_node);
  }
  return output;
}

// Reinterprets underlying buffer type to match destination vector.
void ExtractRawAudioData(AudioFrameOutputNode^ node,
                         std::vector<float>* destination) {
  AudioFrame^ audio_frame = node->GetFrame();
  AudioBuffer^ audio_buffer =
      audio_frame->LockBuffer(AudioBufferAccessMode::Read);
  IMemoryBufferReference^ memory_buffer_reference =
      audio_buffer->CreateReference();

  ComPtr<IMemoryBufferByteAccess> memory_byte_access;
  HRESULT hr = reinterpret_cast<IInspectable*>(memory_buffer_reference)
                   ->QueryInterface(IID_PPV_ARGS(&memory_byte_access));
  CheckResult(hr);

  BYTE* data = nullptr;
  UINT32 capacity = 0;
  hr = memory_byte_access->GetBuffer(&data, &capacity);
  CheckResult(hr);

  // Audio data is float data, so the buffer must be a multiple of 4.
  SB_DCHECK(capacity % sizeof(float) == 0);

  if (capacity > 0) {
    float* typed_data = reinterpret_cast<float*>(data);
    const size_t typed_data_size = capacity / sizeof(float);
    destination->insert(destination->end(), typed_data,
                        typed_data + typed_data_size);
  }
}

// Timer useful for detecting that the microphone has been muted for a certain
// amount of time.
class MutedTrigger {
 public:
  void SignalMuted() {
    if (state_ == kIsMuted) {
      return;
    }
    state_ = kIsMuted;
    time_start_ = SbTimeGetMonotonicNow();
  }

  void SignalSound() {
    state_ = kFoundSound;
  }

  bool IsMuted(SbTimeMonotonic duration_theshold) const {
    if (state_ != kIsMuted) {
      return false;
    }
    SbTimeMonotonic duration = SbTimeGetMonotonicNow() - time_start_;
    return duration > duration_theshold;
  }

 private:
  enum State {
    kInitialized,
    kIsMuted,
    kFoundSound
  };
  State state_ = kInitialized;
  SbTimeMonotonic time_start_ = 0;
};

// MicrophoneProcessor encapsulates Microsoft's audio api. All available
// microphones are queried and instantiated. This class will mix the audio
// together into one signed 16-bit pcm stream.
//
// When the microphone is created it will find all available microphones and
// immediately start recording. A callback will be created which will process
// audio data when new samples are available. The Microphone will stop
// recording when Close() is called.
class MicrophoneProcessor : public SimpleThread {
 public:
  // This will try and create a microphone. This will fail (return null) if
  // there are not available microphones.
  static scoped_ptr<MicrophoneProcessor> TryCreateAndStartRecording(
      size_t max_num_samples,
      int sample_rate) {
    scoped_ptr<MicrophoneProcessor> output;

    std::vector<DeviceInformation^> microphone_devices =
        GetAllMicrophoneDevices();
    if (microphone_devices.empty()) {  // Unexpected condition.
      return output.Pass();
    }

    output.reset(new MicrophoneProcessor(
        max_num_samples, sample_rate, microphone_devices));

    if (output->input_nodes_.empty()) {
      output.reset(nullptr);
    }
    return output.Pass();
  }

  virtual ~MicrophoneProcessor() {
    SimpleThread::Join();
    audio_graph_->Stop();
  }

  // Returns the number of elements that have been written, or -1 if there
  // was a read error.
  int Read(int16_t* out_audio_data, size_t out_audio_count) {
    ScopedLock lock(mutex_);
    if (muted_timer_.IsMuted(kTimeMutedThreshold)) {
      return -1;
    }

    out_audio_count = std::min(out_audio_count,
                               pcm_audio_data_.size());
    using iter = std::vector<int16_t>::iterator;
    iter it_begin = pcm_audio_data_.begin();
    iter it_end = pcm_audio_data_.begin() + out_audio_count;
    std::copy(it_begin, it_end, out_audio_data);
    pcm_audio_data_.erase(it_begin, it_end);
    return static_cast<int>(out_audio_count);
  }

 private:
  explicit MicrophoneProcessor(
      size_t max_num_samples,
      int sample_rate,
      const std::vector<DeviceInformation^>& microphone_devices)
          : SimpleThread("MicrophoneProcessor"),
            max_num_samples_(max_num_samples) {
    audio_graph_ = CreateAudioGraph(AudioRenderCategory::Speech,
                                    QuantumSizeSelectionMode::SystemDefault);
    wave_encoder_ =
        AudioEncodingProperties::CreatePcm(sample_rate, kNumChannels,
                                           16);  // 4-byte float.
    SB_DCHECK(audio_graph_);
    input_nodes_ = GenerateAudioInputNodes(microphone_devices, wave_encoder_,
                                           audio_graph_);
    for (AudioDeviceInputNode^ input_node : input_nodes_) {
      AudioFrameOutputNode^ audio_frame_node =
          audio_graph_->CreateFrameOutputNode(wave_encoder_);
      audio_frame_node->ConsumeInput = true;
      input_node->AddOutgoingConnection(audio_frame_node);
      audio_channel_.emplace_back(new std::vector<float>());
      audio_frame_nodes_.push_back(audio_frame_node);
    }
    // Update the audio data whenever a new audio sample has been finished.
    audio_graph_->Start();
    SimpleThread::Start();
  }

  void Run() override {
    while (!join_called()) {
      SleepMilliseconds(1);
      Process();
    }
  }

  void Process() {
    ScopedLock lock(mutex_);
    if (audio_frame_nodes_.empty()) {
      return;
    }
    for (size_t i = 0; i < audio_frame_nodes_.size(); ++i) {
      ExtractRawAudioData(audio_frame_nodes_[i], audio_channel_[i].get());
    }

    size_t num_elements = max_num_samples_;
    for (const auto& audio_datum : audio_channel_) {
      num_elements = std::min(audio_datum->size(), num_elements);
    }
    if (num_elements == 0) {
      return;
    }

    bool is_muted = true;
    // Mix all available audio channels together and convert to output buffer
    // format. Detect if audio is muted.
    for (int i = 0; i < num_elements; ++i) {
      float mixed_sample = 0.0f;
      for (const auto& audio_datum : audio_channel_) {
        float sample = (*audio_datum)[i];
        if (sample != 0.0) {
          is_muted = false;
        }
        mixed_sample += sample;
      }
      pcm_audio_data_.push_back(To16BitPcm(mixed_sample));
    }

    // Trim values from finished pcm_data if the buffer has exceeded it's
    // allowed size.
    if (pcm_audio_data_.size() > max_num_samples_) {
      size_t num_delete = pcm_audio_data_.size() - max_num_samples_;
      pcm_audio_data_.erase(pcm_audio_data_.begin(),
                            pcm_audio_data_.begin() + num_delete);
    }

    if (is_muted) {
      muted_timer_.SignalMuted();
    } else {
      muted_timer_.SignalSound();
    }
    // Trim values from source channels that were just transfered to
    // pcm_audio_data.
    for (const auto& audio_datum : audio_channel_) {
      audio_datum->erase(audio_datum->begin(),
                         audio_datum->begin() + num_elements);
    }
  }

  AudioGraph^ audio_graph_ = nullptr;
  AudioEncodingProperties^ wave_encoder_;
  std::vector<AudioDeviceInputNode^> input_nodes_;
  std::vector<AudioFrameOutputNode^> audio_frame_nodes_;
  std::vector<std::unique_ptr<std::vector<float>>> audio_channel_;
  std::vector<int16_t> pcm_audio_data_;
  size_t max_num_samples_ = 0;
  MutedTrigger muted_timer_;
  Mutex mutex_;
};

// Implements the SbMicrophonePrivate interface.
class MicrophoneImpl : public SbMicrophonePrivate {
 public:
  MicrophoneImpl(int sample_rate, int buffer_size_bytes)
      : buffer_size_bytes_(buffer_size_bytes),
        sample_rate_(sample_rate) {
  }

  ~MicrophoneImpl() { Close(); }

  bool Open() override {
    if (!microphone_) {
      if (IsUiThread()) {
        SB_LOG(INFO) << "Could not open microphone from UI thread.";
        return false;
      }
      microphone_ = MicrophoneProcessor::TryCreateAndStartRecording(
          buffer_size_bytes_ / kOutputBytesPerSample,
          sample_rate_);
    }
    return microphone_ != nullptr;
  }

  bool Close() override {
    microphone_.reset(nullptr);
    return true;
  }

  int Read(void* out_audio_data, int audio_data_size) override {
    if (!microphone_) {
      return -1;
    }
    int16_t* pcm_buffer = reinterpret_cast<int16*>(out_audio_data);
    size_t pcm_buffer_count = audio_data_size / kOutputBytesPerSample;
    int n_samples = microphone_->Read(pcm_buffer, pcm_buffer_count);
    if (n_samples < 0) {
      return -1;  // Is error.
    } else {
      return n_samples * kOutputBytesPerSample;
    }
  }

 private:
  const int buffer_size_bytes_;
  const int sample_rate_;
  scoped_ptr<MicrophoneProcessor> microphone_;
};

// Singleton access is required by the microphone interface as specified by
// nplb.
const SbMicrophoneId kSingletonId =
    reinterpret_cast<SbMicrophoneId>(0x1);
starboard::atomic_pointer<MicrophoneImpl*> s_singleton_pointer;

}  // namespace.

int SbMicrophonePrivate::GetAvailableMicrophones(
    SbMicrophoneInfo* out_info_array,
    int info_array_size) {

  std::vector<DeviceInformation^> mic_devices = GetAllMicrophoneDevices();
  if (mic_devices.empty()) {
    return 0;
  }
  if (out_info_array && (info_array_size >= 1)) {
    SbMicrophoneInfo info;
    info.id = kSingletonId;
    info.type = kSBMicrophoneAnalogHeadset;
    info.max_sample_rate_hz = kMaxSampleRate;
    info.min_read_size = kMinReadSizeBytes;

#if SB_API_VERSION >= 9
    std::stringstream all_mic_names;
    for (size_t i = 0; i < mic_devices.size(); ++i) {
      DeviceInformation^ mic_dev = mic_devices[i];
      if (i > 0) {
        all_mic_names << ", ";
      }
      all_mic_names << "[" << platformStringToString(mic_dev->Name) << "]";
    }
    SbStringCopy(info.label, all_mic_names.str().c_str(),
                 SB_ARRAY_SIZE(info.label));
#endif  // SB_API_VERSION >= 9
    out_info_array[0] = info;
  }
  return 1;
}

bool SbMicrophonePrivate::IsMicrophoneSampleRateSupported(
    SbMicrophoneId id,
    int sample_rate_in_hz) {
  if (!SbMicrophoneIdIsValid(id)) {
    return false;
  }
  return (kMinSampleRate <= sample_rate_in_hz) &&
         (sample_rate_in_hz <= kMaxSampleRate);
}

SbMicrophone SbMicrophonePrivate::CreateMicrophone(SbMicrophoneId id,
                                                   int sample_rate_in_hz,
                                                   int buffer_size_bytes) {
  if (!SbMicrophoneIdIsValid(id)) {
    return kSbMicrophoneInvalid;
  }
  if (sample_rate_in_hz < kMinSampleRate) {
    return kSbMicrophoneInvalid;
  }
  if (sample_rate_in_hz > kMaxSampleRate) {
    return kSbMicrophoneInvalid;
  }
  if (buffer_size_bytes <= 0) {
    return kSbMicrophoneInvalid;
  }
  // Required to conform to nplb test.
  if (buffer_size_bytes >= (std::numeric_limits<int>::max() - 1)) {
    return kSbMicrophoneInvalid;
  }
  // Id will either by 1 or 0. At this time there is only one microphone.
  SB_DCHECK(id == kSingletonId);
  if (s_singleton_pointer.load()) {
    return kSbMicrophoneInvalid;
  }
  MicrophoneImpl* new_microphone =
      new MicrophoneImpl(sample_rate_in_hz, buffer_size_bytes);

  s_singleton_pointer.store(new_microphone);
  return new_microphone;
}

void SbMicrophonePrivate::DestroyMicrophone(SbMicrophone microphone) {
  SB_DCHECK(microphone == s_singleton_pointer.load());
  s_singleton_pointer.store(nullptr);
  delete microphone;
}
