// 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 <memory>

#include "cobalt/speech/microphone_manager.h"

namespace cobalt {
namespace speech {

namespace {
// Size of an audio buffer.
const int kBufferSizeInBytes = 8 * 1024;
// The frequency which we read the data from devices.
const float kMicReadRateInHertz = 60.0f;
}  // namespace

MicrophoneManager::MicrophoneManager(
    const DataReceivedCallback& data_received,
    const SuccessfulOpenCallback& successful_open,
    const CompletionCallback& completion, const ErrorCallback& error,
    const MicrophoneCreator& microphone_creator)
    : data_received_callback_(data_received),
      completion_callback_(completion),
      error_callback_(error),
      successful_open_callback_(successful_open),
      microphone_creator_(microphone_creator),
      state_(kStopped),
      thread_("microphone_thread") {
  thread_.StartWithOptions(
      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
}

MicrophoneManager::~MicrophoneManager() {
  thread_.message_loop()->task_runner()->PostBlockingTask(
      FROM_HERE,
      base::Bind(&MicrophoneManager::DestroyInternal, base::Unretained(this)));
}

void MicrophoneManager::Open() {
  thread_.message_loop()->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&MicrophoneManager::OpenInternal, base::Unretained(this)));
}

void MicrophoneManager::Close() {
  thread_.message_loop()->task_runner()->PostBlockingTask(
      FROM_HERE,
      base::Bind(&MicrophoneManager::CloseInternal, base::Unretained(this)));
}

bool MicrophoneManager::CreateIfNecessary() {
  DCHECK(thread_.task_runner()->BelongsToCurrentThread());

  if (microphone_) {
    return true;
  }

  microphone_ = microphone_creator_.Run(kBufferSizeInBytes);
  if (microphone_ && microphone_->IsValid()) {
    state_ = kStopped;
    return true;
  } else {
    DLOG(WARNING) << "Microphone creation failed.";
    microphone_.reset();
    state_ = kError;
    error_callback_.Run(MicrophoneError::kAudioCapture,
                        "No microphone available.");
    return false;
  }
}

void MicrophoneManager::OpenInternal() {
  DCHECK(thread_.task_runner()->BelongsToCurrentThread());

  // Try to create a valid microphone if necessary.
  if (state_ == kStarted || !CreateIfNecessary()) {
    return;
  }

  DCHECK(microphone_);
  if (!microphone_->Open()) {
    state_ = kError;
    error_callback_.Run(MicrophoneError::kAborted, "Microphone open failed.");
    return;
  }

  if (!successful_open_callback_.is_null()) {
    successful_open_callback_.Run();
  }
  poll_mic_events_timer_.emplace();
  // Setup a timer to poll for input events.
  poll_mic_events_timer_->Start(
      FROM_HERE,
      base::TimeDelta::FromMicroseconds(static_cast<int64>(
          base::Time::kMicrosecondsPerSecond / kMicReadRateInHertz)),
      this, &MicrophoneManager::Read);
  state_ = kStarted;
}

void MicrophoneManager::CloseInternal() {
  DCHECK(thread_.task_runner()->BelongsToCurrentThread());

  if (state_ == kStopped) {
    return;
  }

  if (poll_mic_events_timer_) {
    poll_mic_events_timer_->Stop();
  }

  if (microphone_) {
    if (!microphone_->Close()) {
      state_ = kError;
      error_callback_.Run(MicrophoneError::kAborted,
                          "Microphone close failed.");
      return;
    }
    completion_callback_.Run();
    state_ = kStopped;
  }
}

void MicrophoneManager::Read() {
  DCHECK(thread_.task_runner()->BelongsToCurrentThread());

  DCHECK(state_ == kStarted);
  DCHECK(microphone_);
  DCHECK(microphone_->MinMicrophoneReadInBytes() <= kBufferSizeInBytes);

  int16_t samples[kBufferSizeInBytes / sizeof(int16_t)];
  int read_bytes =
      microphone_->Read(reinterpret_cast<char*>(samples), kBufferSizeInBytes);
  // If |read_bytes| is zero, nothing should happen.
  if (read_bytes > 0 && read_bytes % sizeof(int16_t) == 0) {
    size_t frames = read_bytes / sizeof(int16_t);
    std::unique_ptr<ShellAudioBus> output_audio_bus(new ShellAudioBus(
        1, frames, ShellAudioBus::kInt16, ShellAudioBus::kInterleaved));
    ShellAudioBus source(1, frames, samples);
    output_audio_bus->Assign(source);
    data_received_callback_.Run(std::move(output_audio_bus));
  } else if (read_bytes != 0) {
    state_ = kError;
    error_callback_.Run(MicrophoneError::kAborted, "Microphone read failed.");
    poll_mic_events_timer_->Stop();
  }
}

void MicrophoneManager::DestroyInternal() {
  DCHECK(thread_.task_runner()->BelongsToCurrentThread());

  microphone_.reset();
  state_ = kStopped;
  poll_mic_events_timer_ = base::nullopt;
}

}  // namespace speech
}  // namespace cobalt
