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

#include "base/file_path.h"
#include "base/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() {
    FilePath exe_path;
    if (!PathService::Get(base::DIR_EXE, &exe_path)) {
      NOTREACHED() << "Failed to get EXE path.";
      return;
    }
    FilePath script_path = exe_path.Append(kWebDriverInitScriptPath);
    std::string script_contents;
    if (!file_util::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> 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, false /*mute_errors*/,
                                          &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(thread_checker_.CalledOnValidThread());
  scoped_refptr<ScriptExecutorResult> executor_result(
      new ScriptExecutorResult(result_handler));
  return ExecuteInternal(params, executor_result);
}

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

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

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

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

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

}  // namespace webdriver
}  // namespace cobalt
