// Copyright 2016 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 "cobalt/speech/sandbox/speech_sandbox.h"

#include "base/path_service.h"
#include "cobalt/dom/window.h"
#include "cobalt/script/environment_settings.h"

namespace cobalt {
namespace speech {
namespace sandbox {

namespace {
// The maximum number of element depth in the DOM tree. Elements at a level
// deeper than this could be discarded, and will not be rendered.
const int kDOMMaxElementDepth = 32;
}  // namespace

SpeechSandbox::SpeechSandbox(const std::string& file_path_string,
                             const FilePath& trace_log_path) {
  trace_to_file_.reset(new trace_event::ScopedTraceToFile(trace_log_path));

  network::NetworkModule::Options network_options;
  network_options.https_requirement = network::kHTTPSOptional;
  network_module_.reset(new network::NetworkModule(network_options));

  GURL url(file_path_string);
  if (url.is_valid()) {
    audio_loader_.reset(new AudioLoader(
        url, network_module_.get(),
        base::Bind(&SpeechSandbox::OnLoadingDone, base::Unretained(this))));
  } else {
    FilePath file_path(file_path_string);
    if (!file_path.IsAbsolute()) {
      FilePath exe_path;
      PathService::Get(base::FILE_EXE, &exe_path);
      DCHECK(exe_path.IsAbsolute());
      std::string exe_path_string(exe_path.value());
      std::size_t found = exe_path_string.find_last_of("/\\");
      DCHECK_NE(found, std::string::npos);
      // Find the executable directory. Using exe_path.DirName() doesn't work
      // on Windows based platforms due to the path is mixed with "/" and "\".
      exe_path_string = exe_path_string.substr(0, found);
      file_path = FilePath(exe_path_string).Append(file_path_string);
      DCHECK(file_path.IsAbsolute());
    }

    dom::DOMSettings::Options dom_settings_options;
    dom_settings_options.microphone_options.enable_fake_microphone = true;
    dom_settings_options.microphone_options.file_path = file_path;

    StartRecognition(dom_settings_options);
  }
}

SpeechSandbox::~SpeechSandbox() {
  if (speech_recognition_) {
    speech_recognition_->Stop();
  }
}

void SpeechSandbox::StartRecognition(
    const dom::DOMSettings::Options& dom_settings_options) {
  scoped_ptr<script::EnvironmentSettings> environment_settings(
      new dom::DOMSettings(kDOMMaxElementDepth, NULL, network_module_.get(),
                           NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                           dom_settings_options));
  DCHECK(environment_settings);

  speech_recognition_ = new SpeechRecognition(environment_settings.get());
  speech_recognition_->set_continuous(true);
  speech_recognition_->set_interim_results(true);
  speech_recognition_->Start(NULL);
}

void SpeechSandbox::OnLoadingDone(const uint8* data, int size) {
  dom::DOMSettings::Options dom_settings_options;
  dom_settings_options.microphone_options.enable_fake_microphone = true;
  dom_settings_options.microphone_options.external_audio_data = data;
  dom_settings_options.microphone_options.audio_data_size = size;

  StartRecognition(dom_settings_options);
}

}  // namespace sandbox
}  // namespace speech
}  // namespace cobalt
