// Copyright 2015 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/webdriver/script_executor.h"

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/lazy_instance.h"
#include "base/path_service.h"
#include "cobalt/script/source_code.h"

namespace cobalt {
namespace webdriver {
namespace {
// Path to the script to initialize the script execution harness.
const char kWebDriverInitScriptPath[] = "webdriver/webdriver-init.js";

// Wrapper around a scoped_refptr<script::SourceCode> instance. The script
// at kWebDriverInitScriptPath will be loaded from disk and a new
// script::SourceCode will be created.
class LazySourceLoader {
 public:
  LazySourceLoader() {
    base::FilePath exe_path;
    if (!base::PathService::Get(base::DIR_EXE, &exe_path)) {
      NOTREACHED() << "Failed to get EXE path.";
      return;
    }
    base::FilePath script_path = exe_path.Append(kWebDriverInitScriptPath);
    std::string script_contents;
    if (!base::ReadFileToString(script_path, &script_contents)) {
      NOTREACHED() << "Failed to read script contents.";
      return;
    }
    source_code_ = script::SourceCode::CreateSourceCode(
        script_contents.c_str(),
        base::SourceLocation(kWebDriverInitScriptPath, 1, 1));
  }
  const scoped_refptr<script::SourceCode>& source_code() {
    return source_code_;
  }

 private:
  scoped_refptr<script::SourceCode> source_code_;
};

// The script only needs to be loaded once, so allow it to persist as a
// LazyInstance and be shared amongst different WindowDriver instances.
base::LazyInstance<LazySourceLoader>::DestructorAtExit lazy_source_loader =
    LAZY_INSTANCE_INITIALIZER;
}  // namespace

void ScriptExecutor::LoadExecutorSourceCode() { lazy_source_loader.Get(); }

scoped_refptr<ScriptExecutor> ScriptExecutor::Create(
    ElementMapping* element_mapping,
    const scoped_refptr<script::GlobalEnvironment>& global_environment) {
  // This could be NULL if there was an error loading the harness source from
  // disk.
  scoped_refptr<script::SourceCode> source =
      lazy_source_loader.Get().source_code();
  if (!source) {
    return NULL;
  }

  // Create a new ScriptExecutor and bind it to the global object.
  scoped_refptr<ScriptExecutor> script_executor =
      new ScriptExecutor(element_mapping);
  global_environment->Bind("webdriverExecutor", script_executor);

  // Evaluate the harness initialization script.
  std::string result;
  if (!global_environment->EvaluateScript(source, &result)) {
    return NULL;
  }

  // The initialization script should have set this.
  DCHECK(script_executor->execute_script_harness());
  return script_executor;
}

bool ScriptExecutor::Execute(
    const scoped_refptr<ScriptExecutorParams>& params,
    ScriptExecutorResult::ResultHandler* result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  scoped_refptr<ScriptExecutorResult> executor_result(
      new ScriptExecutorResult(result_handler));
  return ExecuteInternal(params, executor_result);
}

void ScriptExecutor::set_execute_script_harness(
    const ExecuteFunctionCallbackHolder& callback) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  execute_callback_.emplace(this, callback);
}

const ScriptExecutor::ExecuteFunctionCallbackHolder*
ScriptExecutor::execute_script_harness() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (execute_callback_) {
    return &(execute_callback_->referenced_value());
  } else {
    return NULL;
  }
}

scoped_refptr<dom::Element> ScriptExecutor::IdToElement(const std::string& id) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(element_mapping_);
  return element_mapping_->IdToElement(protocol::ElementId(id));
}

std::string ScriptExecutor::ElementToId(
    const scoped_refptr<dom::Element>& element) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(element_mapping_);
  return element_mapping_->ElementToId(element).id();
}

bool ScriptExecutor::ExecuteInternal(
    const scoped_refptr<ScriptExecutorParams>& params,
    const scoped_refptr<ScriptExecutorResult>& result_handler) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(params);
  DCHECK(result_handler);
  ExecuteFunctionCallback::ReturnValue callback_result =
      execute_callback_->value().Run(params, result_handler);
  return !callback_result.exception;
}

}  // namespace webdriver
}  // namespace cobalt
