/*
 * 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 <algorithm>
#include <vector>

#include "base/json/json_reader.h"
#include "base/run_loop.h"
#include "cobalt/dom/document.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/webdriver/script_executor.h"
#include "cobalt/webdriver/testing/stub_window.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::DefaultValue;
using ::testing::Return;

namespace cobalt {
namespace webdriver {
namespace {

class MockElementMapping : public ElementMapping {
 public:
  MOCK_METHOD1(ElementToId,
               protocol::ElementId(const scoped_refptr<dom::Element>&));
  MOCK_METHOD1(IdToElement,
               scoped_refptr<dom::Element>(const protocol::ElementId& id));
};

class MockScriptExecutorResult : public ScriptExecutorResult::ResultHandler {
 public:
  MOCK_METHOD1(OnResult, void(const std::string&));
  MOCK_METHOD0(OnTimeout, void());
};

class JSONScriptExecutorResult : public ScriptExecutorResult::ResultHandler {
 public:
  void OnResult(const std::string& result) {
    json_result_.reset(base::JSONReader::Read(result.c_str()));
  }
  void OnTimeout() { NOTREACHED(); }
  base::Value* json_result() { return json_result_.get(); }

 private:
  scoped_ptr<base::Value> json_result_;
};

class ScriptExecutorTest : public ::testing::Test {
 protected:
  void SetUp() OVERRIDE {
    stub_window_.reset(new testing::StubWindow());
    script_executor_ =
        ScriptExecutor::Create(&element_mapping_, global_environment());

    ON_CALL(element_mapping_, IdToElement(_))
        .WillByDefault(Return(scoped_refptr<dom::Element>()));
    ON_CALL(element_mapping_, ElementToId(_))
        .WillByDefault(Return(protocol::ElementId("bad-id")));
  }

  scoped_refptr<dom::Window> window() { return stub_window_->window(); }
  scoped_refptr<script::GlobalEnvironment> global_environment() {
    return stub_window_->global_environment();
  }

 protected:
  scoped_ptr<testing::StubWindow> stub_window_;
  MockElementMapping element_mapping_;
  scoped_refptr<ScriptExecutor> script_executor_;
};

}  // namespace

TEST_F(ScriptExecutorTest, CreateSyncScript) {
  scoped_refptr<ScriptExecutorParams> params =
      ScriptExecutorParams::Create(global_environment(), "return 5;", "[]");
  ASSERT_TRUE(params);
  EXPECT_NE(reinterpret_cast<intptr_t>(params->function_object()), NULL);
  EXPECT_STREQ(params->json_args().c_str(), "[]");
  EXPECT_EQ(params->async_timeout(), base::nullopt);
}

TEST_F(ScriptExecutorTest, CreateAsyncScript) {
  scoped_refptr<ScriptExecutorParams> params =
      ScriptExecutorParams::Create(global_environment(), "return 5;", "[]",
                                   base::TimeDelta::FromMilliseconds(5));
  ASSERT_TRUE(params);
  EXPECT_NE(reinterpret_cast<intptr_t>(params->function_object()), NULL);
  EXPECT_STREQ(params->json_args().c_str(), "[]");
  EXPECT_EQ(params->async_timeout(), 5);
}

TEST_F(ScriptExecutorTest, CreateInvalidScript) {
  scoped_refptr<ScriptExecutorParams> params =
      ScriptExecutorParams::Create(global_environment(), "retarn 5ish;", "[]");
  ASSERT_TRUE(params);
  EXPECT_EQ(reinterpret_cast<intptr_t>(params->function_object()), NULL);
}

TEST_F(ScriptExecutorTest, ExecuteSync) {
  scoped_refptr<ScriptExecutorParams> params = ScriptExecutorParams::Create(
      global_environment(), "return \"retval\";", "[]");
  ASSERT_TRUE(params);
  MockScriptExecutorResult result_handler;
  EXPECT_CALL(result_handler, OnResult(std::string("\"retval\"")));
  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));
}

TEST_F(ScriptExecutorTest, ExecuteAsync) {
  // Create a script that will call the async callback after 50 ms, with
  // an async timeout of 100 ms.
  scoped_refptr<ScriptExecutorParams> params = ScriptExecutorParams::Create(
      global_environment(),
      "var callback = arguments[0];"
      "window.setTimeout(function() { callback(72); }, 50);",
      "[]", base::TimeDelta::FromMilliseconds(100));
  ASSERT_TRUE(params);
  MockScriptExecutorResult result_handler;
  EXPECT_CALL(result_handler, OnResult(std::string("72")));
  EXPECT_CALL(result_handler, OnTimeout()).Times(0);

  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));

  // Let the message loop run for 200ms to allow enough time for the async
  // script to fire the callback.
  base::RunLoop run_loop;
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(),
      base::TimeDelta::FromMilliseconds(200));
  run_loop.Run();
}

TEST_F(ScriptExecutorTest, AsyncTimeout) {
  // Create a script that will call the async callback after 10 seconds, with
  // an async timeout of 100 ms.
  scoped_refptr<ScriptExecutorParams> params = ScriptExecutorParams::Create(
      global_environment(),
      "var callback = arguments[0];"
      "window.setTimeout(function() { callback(72); }, 10000);",
      "[]", base::TimeDelta::FromMilliseconds(100));
  ASSERT_TRUE(params);
  MockScriptExecutorResult result_handler;
  EXPECT_CALL(result_handler, OnResult(_)).Times(0);
  EXPECT_CALL(result_handler, OnTimeout()).Times(1);

  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));

  // Let the message loop run for 200ms to allow enough time for the async
  // timeout to fire.
  base::RunLoop run_loop;
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(),
      base::TimeDelta::FromMilliseconds(200));
  run_loop.Run();
}

TEST_F(ScriptExecutorTest, ScriptThrowsException) {
  scoped_refptr<ScriptExecutorParams> params =
      ScriptExecutorParams::Create(global_environment(), "throw Error()", "[]");
  ASSERT_TRUE(params);
  MockScriptExecutorResult result_handler;
  EXPECT_FALSE(script_executor_->Execute(params, &result_handler));
}

TEST_F(ScriptExecutorTest, ConvertBoolean) {
  scoped_refptr<ScriptExecutorParams> params = ScriptExecutorParams::Create(
      global_environment(), "return arguments[0];", "[true]");
  ASSERT_TRUE(params);
  MockScriptExecutorResult result_handler;
  EXPECT_CALL(result_handler, OnResult(std::string("true")));
  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));

  params = ScriptExecutorParams::Create(global_environment(),
                                        "return arguments[0];", "[false]");
  ASSERT_TRUE(params);
  EXPECT_CALL(result_handler, OnResult(std::string("false")));
  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));
}

TEST_F(ScriptExecutorTest, ConvertNull) {
  scoped_refptr<ScriptExecutorParams> params = ScriptExecutorParams::Create(
      global_environment(), "return arguments[0];", "[null]");
  ASSERT_TRUE(params);
  MockScriptExecutorResult result_handler;
  EXPECT_CALL(result_handler, OnResult(std::string("null")));
  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));
}

TEST_F(ScriptExecutorTest, ConvertNumericType) {
  scoped_refptr<ScriptExecutorParams> params = ScriptExecutorParams::Create(
      global_environment(), "return arguments[0];", "[6]");
  ASSERT_TRUE(params);
  MockScriptExecutorResult result_handler;
  EXPECT_CALL(result_handler, OnResult(std::string("6")));
  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));

  params = ScriptExecutorParams::Create(global_environment(),
                                        "return arguments[0];", "[-6.4]");
  ASSERT_TRUE(params);
  EXPECT_CALL(result_handler, OnResult(std::string("-6.4")));
  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));
}

TEST_F(ScriptExecutorTest, ConvertString) {
  scoped_refptr<ScriptExecutorParams> params = ScriptExecutorParams::Create(
      global_environment(), "return arguments[0];", "[\"Mr. T\"]");
  ASSERT_TRUE(params);
  MockScriptExecutorResult result_handler;
  EXPECT_CALL(result_handler, OnResult(std::string("\"Mr. T\"")));
  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));
}

TEST_F(ScriptExecutorTest, ConvertWebElement) {
  // Create a dom::Element for the MockElementMapping to return.
  scoped_refptr<dom::Element> element =
      window()->document()->CreateElement("p");
  EXPECT_CALL(element_mapping_, IdToElement(protocol::ElementId("id123")))
      .WillRepeatedly(Return(element));
  EXPECT_CALL(element_mapping_, ElementToId(element))
      .WillRepeatedly(Return(protocol::ElementId("id123")));

  // Create a script that will pass a web element argument as a parameter, and
  // return it back. This will invoke the lookup to and from an id.
  scoped_refptr<ScriptExecutorParams> params =
      ScriptExecutorParams::Create(global_environment(), "return arguments[0];",
                                   "[ {\"ELEMENT\": \"id123\"} ]");
  ASSERT_TRUE(params);

  // Execute the script and parse the result as JSON, ensuring we got the same
  // web element.
  JSONScriptExecutorResult result_handler;
  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));
  ASSERT_TRUE(result_handler.json_result());

  std::string element_id;
  base::DictionaryValue* dictionary_value;
  ASSERT_TRUE(result_handler.json_result()->GetAsDictionary(&dictionary_value));
  EXPECT_TRUE(dictionary_value->GetString(protocol::ElementId::kElementKey,
                                          &element_id));
  EXPECT_STREQ(element_id.c_str(), "id123");
}

TEST_F(ScriptExecutorTest, ConvertArray) {
  // Create a script that takes an array of numbers as input, and returns an
  // array of those numbers incremented by one.
  scoped_refptr<ScriptExecutorParams> params = ScriptExecutorParams::Create(
      global_environment(),
      "return [ (arguments[0][0]+1), (arguments[0][1]+1) ];", "[ [5, 6] ]");
  ASSERT_TRUE(params);

  JSONScriptExecutorResult result_handler;
  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));
  ASSERT_TRUE(result_handler.json_result());

  base::ListValue* list_value;
  ASSERT_TRUE(result_handler.json_result()->GetAsList(&list_value));
  ASSERT_EQ(list_value->GetSize(), 2);

  int value;
  EXPECT_TRUE(list_value->GetInteger(0, &value));
  EXPECT_EQ(value, 6);
  EXPECT_TRUE(list_value->GetInteger(1, &value));
  EXPECT_EQ(value, 7);
}

TEST_F(ScriptExecutorTest, ConvertObject) {
  // Create a script that takes an Object with two properties as input, and
  // returns an Object with one property that is the sum of the other Object's
  // properties.
  scoped_refptr<ScriptExecutorParams> params = ScriptExecutorParams::Create(
      global_environment(),
      "return {\"sum\": arguments[0].a + arguments[0].b};",
      "[ {\"a\":5, \"b\":6} ]");
  ASSERT_TRUE(params);

  JSONScriptExecutorResult result_handler;
  EXPECT_TRUE(script_executor_->Execute(params, &result_handler));
  ASSERT_TRUE(result_handler.json_result());

  int value;
  base::DictionaryValue* dictionary_value;
  ASSERT_TRUE(result_handler.json_result()->GetAsDictionary(&dictionary_value));
  EXPECT_TRUE(dictionary_value->GetInteger("sum", &value));
  EXPECT_EQ(value, 11);
}

}  // namespace webdriver
}  // namespace cobalt
