// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/autofill_assistant/browser/script_executor.h"

#include <map>

#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "components/autofill_assistant/browser/client_memory.h"
#include "components/autofill_assistant/browser/mock_run_once_callback.h"
#include "components/autofill_assistant/browser/mock_service.h"
#include "components/autofill_assistant/browser/mock_ui_controller.h"
#include "components/autofill_assistant/browser/mock_web_controller.h"
#include "components/autofill_assistant/browser/service.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace autofill_assistant {

namespace {

using ::testing::AllOf;
using ::testing::Contains;
using ::testing::DoAll;
using ::testing::Field;
using ::testing::NiceMock;
using ::testing::Pair;
using ::testing::SaveArg;
using ::testing::StrEq;
using ::testing::StrictMock;
using ::testing::_;

class ScriptExecutorTest : public testing::Test, public ScriptExecutorDelegate {
 public:
  void SetUp() override {
    executor_ = std::make_unique<ScriptExecutor>("script path", this);

    // In this test, "tell" actions always succeed and "click" actions always
    // fail. The following makes a click action fail immediately
    ON_CALL(mock_web_controller_, OnElementExists(_, _))
        .WillByDefault(RunOnceCallback<1>(true));
    ON_CALL(mock_web_controller_, OnClickElement(_, _))
        .WillByDefault(RunOnceCallback<1>(false));
  }

 protected:
  ScriptExecutorTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME) {}

  Service* GetService() override { return &mock_service_; }

  UiController* GetUiController() override { return &mock_ui_controller_; }

  WebController* GetWebController() override { return &mock_web_controller_; }

  ClientMemory* GetClientMemory() override { return &memory_; }

  const std::map<std::string, std::string>& GetParameters() override {
    return parameters_;
  }

  autofill::PersonalDataManager* GetPersonalDataManager() override {
    return nullptr;
  }

  content::WebContents* GetWebContents() override { return nullptr; }

  std::string Serialize(const google::protobuf::MessageLite& message) {
    std::string output;
    message.SerializeToString(&output);
    return output;
  }

  // scoped_task_environment_ must be first to guarantee other field
  // creation run in that environment.
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  Script script_;
  ClientMemory memory_;
  StrictMock<MockService> mock_service_;
  NiceMock<MockWebController> mock_web_controller_;
  NiceMock<MockUiController> mock_ui_controller_;
  std::unique_ptr<ScriptExecutor> executor_;
  std::map<std::string, std::string> parameters_;
  StrictMock<base::MockCallback<ScriptExecutor::RunScriptCallback>>
      executor_callback_;
};

TEST_F(ScriptExecutorTest, GetActionsFails) {
  EXPECT_CALL(mock_service_, OnGetActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(false, ""));
  EXPECT_CALL(executor_callback_,
              Run(AllOf(Field(&ScriptExecutor::Result::success, false),
                        Field(&ScriptExecutor::Result::at_end,
                              ScriptExecutor::CONTINUE))));
  executor_->Run(executor_callback_.Get());
}

TEST_F(ScriptExecutorTest, ForwardParameters) {
  parameters_["param1"] = "value1";
  parameters_["param2"] = "value2";
  EXPECT_CALL(mock_service_,
              OnGetActions(StrEq("script path"),
                           AllOf(Contains(Pair("param1", "value1")),
                                 Contains(Pair("param2", "value2"))),
                           _))
      .WillOnce(RunOnceCallback<2>(true, ""));

  EXPECT_CALL(executor_callback_,
              Run(Field(&ScriptExecutor::Result::success, true)));
  executor_->Run(executor_callback_.Get());
}

TEST_F(ScriptExecutorTest, RunOneActionReportAndReturn) {
  ActionsResponseProto actions_response;
  actions_response.set_server_payload("payload");
  actions_response.add_actions()
      ->mutable_click()
      ->mutable_element_to_click()
      ->add_selectors("will fail");

  EXPECT_CALL(mock_service_, OnGetActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response)));

  std::vector<ProcessedActionProto> processed_actions_capture;
  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _))
      .WillOnce(DoAll(SaveArg<1>(&processed_actions_capture),
                      RunOnceCallback<2>(true, "")));
  EXPECT_CALL(executor_callback_,
              Run(AllOf(Field(&ScriptExecutor::Result::success, true),
                        Field(&ScriptExecutor::Result::at_end,
                              ScriptExecutor::CONTINUE))));
  executor_->Run(executor_callback_.Get());

  ASSERT_EQ(1u, processed_actions_capture.size());
  EXPECT_EQ(OTHER_ACTION_STATUS, processed_actions_capture[0].status());
}

TEST_F(ScriptExecutorTest, RunMultipleActions) {
  ActionsResponseProto initial_actions_response;
  initial_actions_response.set_server_payload("payload1");
  initial_actions_response.add_actions()->mutable_tell()->set_message("1");
  initial_actions_response.add_actions()->mutable_tell()->set_message("2");
  EXPECT_CALL(mock_service_, OnGetActions(StrEq("script path"), _, _))
      .WillOnce(RunOnceCallback<2>(true, Serialize(initial_actions_response)));

  ActionsResponseProto next_actions_response;
  next_actions_response.set_server_payload("payload2");
  next_actions_response.add_actions()->mutable_tell()->set_message("3");
  std::vector<ProcessedActionProto> processed_actions1_capture;
  std::vector<ProcessedActionProto> processed_actions2_capture;
  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _))
      .WillOnce(
          DoAll(SaveArg<1>(&processed_actions1_capture),
                RunOnceCallback<2>(true, Serialize(next_actions_response))))
      .WillOnce(DoAll(SaveArg<1>(&processed_actions2_capture),
                      RunOnceCallback<2>(true, "")));
  EXPECT_CALL(executor_callback_,
              Run(Field(&ScriptExecutor::Result::success, true)));
  executor_->Run(executor_callback_.Get());

  EXPECT_EQ(2u, processed_actions1_capture.size());
  EXPECT_EQ(1u, processed_actions2_capture.size());
}

TEST_F(ScriptExecutorTest, UnsupportedAction) {
  ActionsResponseProto actions_response;
  actions_response.set_server_payload("payload");
  actions_response.add_actions();  // action definition missing

  EXPECT_CALL(mock_service_, OnGetActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response)));

  std::vector<ProcessedActionProto> processed_actions_capture;
  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _))
      .WillOnce(DoAll(SaveArg<1>(&processed_actions_capture),
                      RunOnceCallback<2>(true, "")));
  EXPECT_CALL(executor_callback_,
              Run(Field(&ScriptExecutor::Result::success, true)));
  executor_->Run(executor_callback_.Get());

  ASSERT_EQ(1u, processed_actions_capture.size());
  EXPECT_EQ(UNKNOWN_ACTION_STATUS, processed_actions_capture[0].status());
}

TEST_F(ScriptExecutorTest, StopAfterEnd) {
  ActionsResponseProto actions_response;
  actions_response.set_server_payload("payload");
  actions_response.add_actions()->mutable_stop();

  EXPECT_CALL(mock_service_, OnGetActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response)));

  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, ""));
  EXPECT_CALL(executor_callback_,
              Run(AllOf(Field(&ScriptExecutor::Result::success, true),
                        Field(&ScriptExecutor::Result::at_end,
                              ScriptExecutor::SHUTDOWN))));
  executor_->Run(executor_callback_.Get());
}

TEST_F(ScriptExecutorTest, ResetAfterEnd) {
  ActionsResponseProto actions_response;
  actions_response.set_server_payload("payload");
  actions_response.add_actions()->mutable_reset();

  EXPECT_CALL(mock_service_, OnGetActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response)));

  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, ""));
  EXPECT_CALL(executor_callback_,
              Run(AllOf(Field(&ScriptExecutor::Result::success, true),
                        Field(&ScriptExecutor::Result::at_end,
                              ScriptExecutor::RESTART))));
  executor_->Run(executor_callback_.Get());
}

TEST_F(ScriptExecutorTest, InterruptActionListOnError) {
  ActionsResponseProto initial_actions_response;
  initial_actions_response.set_server_payload("payload");
  initial_actions_response.add_actions()->mutable_tell()->set_message(
      "will pass");
  initial_actions_response.add_actions()
      ->mutable_click()
      ->mutable_element_to_click()
      ->add_selectors("will fail");
  initial_actions_response.add_actions()->mutable_tell()->set_message(
      "never run");

  EXPECT_CALL(mock_service_, OnGetActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, Serialize(initial_actions_response)));

  ActionsResponseProto next_actions_response;
  next_actions_response.set_server_payload("payload2");
  next_actions_response.add_actions()->mutable_tell()->set_message(
      "will run after error");
  std::vector<ProcessedActionProto> processed_actions1_capture;
  std::vector<ProcessedActionProto> processed_actions2_capture;
  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _))
      .WillOnce(
          DoAll(SaveArg<1>(&processed_actions1_capture),
                RunOnceCallback<2>(true, Serialize(next_actions_response))))
      .WillOnce(DoAll(SaveArg<1>(&processed_actions2_capture),
                      RunOnceCallback<2>(true, "")));
  EXPECT_CALL(executor_callback_,
              Run(Field(&ScriptExecutor::Result::success, true)));
  executor_->Run(executor_callback_.Get());

  ASSERT_EQ(2u, processed_actions1_capture.size());
  EXPECT_EQ(ACTION_APPLIED, processed_actions1_capture[0].status());
  EXPECT_EQ(OTHER_ACTION_STATUS, processed_actions1_capture[1].status());

  ASSERT_EQ(1u, processed_actions2_capture.size());
  EXPECT_EQ(ACTION_APPLIED, processed_actions2_capture[0].status());
  // make sure "never run" wasn't the one that was run.
  EXPECT_EQ("will run after error",
            processed_actions2_capture[0].action().tell().message());
}

TEST_F(ScriptExecutorTest, RunDelayedAction) {
  ActionsResponseProto actions_response;
  actions_response.set_server_payload("payload");
  ActionProto* action = actions_response.add_actions();
  action->mutable_tell()->set_message("delayed");
  action->set_action_delay_ms(1000);

  EXPECT_CALL(mock_service_, OnGetActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response)));

  std::vector<ProcessedActionProto> processed_actions_capture;
  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _))
      .WillOnce(DoAll(SaveArg<1>(&processed_actions_capture),
                      RunOnceCallback<2>(true, "")));

  // executor_callback_.Run() not expected to be run just yet, as the action is
  // delayed.
  executor_->Run(executor_callback_.Get());
  EXPECT_TRUE(scoped_task_environment_.MainThreadHasPendingTask());

  // Moving forward in time triggers action execution.
  EXPECT_CALL(executor_callback_,
              Run(Field(&ScriptExecutor::Result::success, true)));
  scoped_task_environment_.FastForwardBy(
      base::TimeDelta::FromMilliseconds(1000));
  EXPECT_FALSE(scoped_task_environment_.MainThreadHasPendingTask());
}

TEST_F(ScriptExecutorTest, HideDetailsWhenFinished) {
  ActionsResponseProto actions_response;
  actions_response.set_server_payload("payload");
  ActionProto click_with_clean_contextual_ui;
  click_with_clean_contextual_ui.set_clean_contextual_ui(true);
  click_with_clean_contextual_ui.mutable_tell()->set_message("clean");
  ;
  *actions_response.add_actions() = click_with_clean_contextual_ui;

  EXPECT_CALL(mock_service_, OnGetActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response)));
  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, ""));
  EXPECT_CALL(executor_callback_,
              Run(Field(&ScriptExecutor::Result::success, true)));
  EXPECT_CALL(mock_ui_controller_, HideDetails());
  executor_->Run(executor_callback_.Get());
}

TEST_F(ScriptExecutorTest, DontHideDetailsIfOtherActionsAreLeft) {
  ActionsResponseProto actions_response;
  actions_response.set_server_payload("payload");
  ActionProto click_with_clean_contextual_ui;
  click_with_clean_contextual_ui.set_clean_contextual_ui(true);
  click_with_clean_contextual_ui.mutable_tell()->set_message("clean");
  *actions_response.add_actions() = click_with_clean_contextual_ui;
  actions_response.add_actions()->mutable_tell()->set_message("Wait no!");

  EXPECT_CALL(mock_service_, OnGetActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response)));
  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, ""));
  EXPECT_CALL(executor_callback_,
              Run(Field(&ScriptExecutor::Result::success, true)));

  EXPECT_CALL(mock_ui_controller_, HideDetails()).Times(0);

  executor_->Run(executor_callback_.Get());
}

TEST_F(ScriptExecutorTest, HideDetailsOnError) {
  ActionsResponseProto actions_response;
  actions_response.set_server_payload("payload");
  actions_response.add_actions()->mutable_tell()->set_message("Hello");
  EXPECT_CALL(mock_service_, OnGetActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(true, Serialize(actions_response)));
  EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _))
      .WillOnce(RunOnceCallback<2>(false, ""));
  EXPECT_CALL(executor_callback_,
              Run(Field(&ScriptExecutor::Result::success, false)));

  EXPECT_CALL(mock_ui_controller_, HideDetails());

  executor_->Run(executor_callback_.Get());
}

}  // namespace
}  // namespace autofill_assistant
