// 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 "cobalt/speech/microphone_fake.h"

#if defined(ENABLE_FAKE_MICROPHONE)

#include <algorithm>
#include <memory>

#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/rand_util.h"
#include "cobalt/audio/audio_file_reader.h"
#include "starboard/file.h"
#include "starboard/memory.h"
#include "starboard/time.h"

namespace cobalt {
namespace speech {

typedef audio::ShellAudioBus ShellAudioBus;

namespace {

const int kMaxBufferSize = 1024 * 1024;
const int kMinMicrophoneReadInBytes = 1024;
// The possiblity of microphone creation failed is 1/20.
const int kCreationRange = 20;
// The possiblity of microphone open failed is 1/20.
const int kOpenRange = 20;
// The possiblity of microphone read failed is 1/300.
const int kReadRange = 300;
// The possiblity of microphone close failed is 1/20.
const int kCloseRange = 20;
const int kFailureNumber = 5;
const int kSupportedMonoChannel = 1;
const char kMicrophoneLabel[] = "FakeMicrophone";

bool ShouldFail(int range) {
  return base::RandGenerator(range) == kFailureNumber;
}

}  // namespace

MicrophoneFake::MicrophoneFake(const Options& options)
    : Microphone(),
      read_data_from_file_(options.audio_data_size == 0),
      file_length_(-1),
      read_index_(0),
      is_valid_(!ShouldFail(kCreationRange)) {
  if (!is_valid_) {
    DLOG(WARNING) << "Mocking microphone creation failed.";
    return;
  }

  if (read_data_from_file_) {
    if (options.file_path) {
      DCHECK(!options.file_path->empty());
      // External input file.
      file_paths_.push_back(options.file_path.value());
    } else {
      base::FilePath audio_files_path;
      CHECK(base::PathService::Get(base::DIR_TEST_DATA, &audio_files_path));
      audio_files_path = audio_files_path.Append(FILE_PATH_LITERAL("cobalt"))
                             .Append(FILE_PATH_LITERAL("speech"))
                             .Append(FILE_PATH_LITERAL("testdata"));

      base::FileEnumerator file_enumerator(audio_files_path,
                                           false /* Not recursive */,
                                           base::FileEnumerator::FILES);
      for (base::FilePath next = file_enumerator.Next(); !next.empty();
           next = file_enumerator.Next()) {
        file_paths_.push_back(next);
      }
    }
  } else {
    file_length_ = std::min(options.audio_data_size, kMaxBufferSize);
    DCHECK_GT(file_length_, 0);
    audio_bus_.reset(new ShellAudioBus(
        kSupportedMonoChannel,
        file_length_ / audio::GetSampleTypeSize(ShellAudioBus::kInt16),
        ShellAudioBus::kInt16, ShellAudioBus::kInterleaved));
    SbMemoryCopy(audio_bus_->interleaved_data(), options.external_audio_data,
                 file_length_);
  }
}

bool MicrophoneFake::Open() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  if (ShouldFail(kOpenRange)) {
    DLOG(WARNING) << "Mocking microphone open failed.";
    return false;
  }

  if (read_data_from_file_) {
    // Read from local files.
    DCHECK_NE(file_paths_.size(), 0u);
    size_t random_index =
        static_cast<size_t>(base::RandGenerator(file_paths_.size()));
    starboard::ScopedFile file(file_paths_[random_index].value().c_str(),
                               kSbFileOpenOnly | kSbFileRead, NULL, NULL);
    DCHECK(file.IsValid());
    int file_buffer_size =
        std::min(static_cast<int>(file.GetSize()), kMaxBufferSize);
    DCHECK_GT(file_buffer_size, 0);

    std::unique_ptr<char[]> audio_input(new char[file_buffer_size]);
    int read_bytes = file.ReadAll(audio_input.get(), file_buffer_size);
    if (read_bytes < 0) {
      return false;
    }

    std::unique_ptr<audio::AudioFileReader> reader(
        audio::AudioFileReader::TryCreate(
            reinterpret_cast<const uint8*>(audio_input.get()), file_buffer_size,
            audio::kSampleTypeInt16));
    const float kSupportedSampleRate = 16000.0f;
    if (!reader) {
      // If it is not a WAV file, read audio data as raw audio.
      audio_bus_.reset(new ShellAudioBus(
          kSupportedMonoChannel,
          file_buffer_size / audio::GetSampleTypeSize(ShellAudioBus::kInt16),
          ShellAudioBus::kInt16, ShellAudioBus::kInterleaved));
      SbMemoryCopy(audio_bus_->interleaved_data(), audio_input.get(),
                   file_buffer_size);
      file_length_ = file_buffer_size;
    } else if (reader->sample_type() != ShellAudioBus::kInt16 ||
               reader->sample_rate() != kSupportedSampleRate ||
               reader->number_of_channels() != kSupportedMonoChannel) {
      // If it is a WAV file but it doesn't meet the audio input criteria, treat
      // it as an error.
      return false;
    } else {
      audio_bus_ = reader->ResetAndReturnAudioBus();
      file_length_ =
          static_cast<int>(reader->number_of_frames() *
                           audio::GetSampleTypeSize(reader->sample_type()));
    }
  }
  return true;
}

int MicrophoneFake::Read(char* out_data, int data_size) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  if (ShouldFail(kReadRange)) {
    DLOG(WARNING) << "Mocking microphone read failed.";
    return -1;
  }

  int copy_bytes = std::min(file_length_ - read_index_, data_size);
  SbMemoryCopy(out_data, audio_bus_->interleaved_data() + read_index_,
               copy_bytes);
  read_index_ += copy_bytes;
  if (read_index_ == file_length_) {
    read_index_ = 0;
  }

  return copy_bytes;
}

bool MicrophoneFake::Close() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  if (read_data_from_file_) {
    audio_bus_.reset();
    file_length_ = -1;
  }

  read_index_ = 0;

  if (ShouldFail(kCloseRange)) {
    DLOG(WARNING) << "Mocking microphone close failed.";
    return false;
  }

  return true;
}

int MicrophoneFake::MinMicrophoneReadInBytes() {
  return kMinMicrophoneReadInBytes;
}

const char* MicrophoneFake::Label() { return kMicrophoneLabel; }

}  // namespace speech
}  // namespace cobalt

#endif  // defined(ENABLE_FAKE_MICROPHONE)
