// 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 "chrome/chrome_cleaner/os/task_scheduler.h"

#include <taskschd.h>

#include <memory>
#include <vector>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/strcat.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
#include "base/time/time.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_variant.h"
#include "base/win/windows_version.h"
#include "chrome/chrome_cleaner/os/system_util_cleaner.h"
#include "chrome/chrome_cleaner/test/test_executables.h"
#include "chrome/chrome_cleaner/test/test_strings.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chrome_cleaner {

namespace {

// The name of the tasks as will be visible in the scheduler so we know we can
// safely delete them if they get stuck for whatever reason.
const wchar_t kTaskName1[] = L"Chrome Cleanup Test task 1 (delete me)";
const wchar_t kTaskName2[] = L"Chrome Cleanup Test task 2 (delete me)";
// Optional descriptions for the above tasks.
const wchar_t kTaskDescription1[] =
    L"Task 1 used only for Chrome Cleanup unit testing.";
const wchar_t kTaskDescription2[] =
    L"Task 2 used only for Chrome Cleanup unit testing.";
// A command-line switch used in testing.
const char kTestSwitch[] = "a_switch";

class TaskSchedulerTests : public testing::Test {
 public:
  void SetUp() override {
    task_scheduler_.reset(TaskScheduler::CreateInstance());
    // In case previous tests failed and left these tasks in the scheduler.
    EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
    EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName2));
    ASSERT_FALSE(IsProcessRunning(kTestProcessExecutableName));
  }

  void TearDown() override {
    // Make sure to not leave tasks behind.
    EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
    EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName2));
    // Make sure every processes launched with scheduled task are completed.
    ASSERT_TRUE(WaitForProcessesStopped(kTestProcessExecutableName));
  }

 protected:
  std::unique_ptr<TaskScheduler> task_scheduler_;
};

}  // namespace

TEST_F(TaskSchedulerTests, DeleteAndIsRegistered) {
  EXPECT_FALSE(task_scheduler_->IsTaskRegistered(kTaskName1));

  // Construct the full-path of the test executable.
  base::FilePath executable_path;
  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &executable_path));
  base::CommandLine command_line(
      executable_path.Append(kTestProcessExecutableName));

  // Validate that the task is properly seen as registered when it is.
  EXPECT_TRUE(task_scheduler_->RegisterTask(
      kTaskName1, kTaskDescription1, command_line,
      TaskScheduler::TRIGGER_TYPE_POST_REBOOT, false));
  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName1));

  // Validate that a task with a similar name is not seen as registered.
  EXPECT_FALSE(task_scheduler_->IsTaskRegistered(kTaskName2));

  // While the first one is still seen as registered, until it gets deleted.
  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName1));
  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
  EXPECT_FALSE(task_scheduler_->IsTaskRegistered(kTaskName1));
  // The other task should still not be registered.
  EXPECT_FALSE(task_scheduler_->IsTaskRegistered(kTaskName2));
}

TEST_F(TaskSchedulerTests, RunAProgramNow) {
  base::FilePath executable_path;
  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &executable_path));
  base::CommandLine command_line(
      executable_path.Append(kTestProcessExecutableName));

  // Create a unique name for a shared event to be waited for in this process
  // and signaled in the test process to confirm it was scheduled and ran.
  const base::string16 event_name =
      base::StrCat({kTestProcessExecutableName, L"-",
                    base::NumberToString16(::GetCurrentProcessId())});
  base::WaitableEvent event(base::win::ScopedHandle(
      ::CreateEvent(nullptr, FALSE, FALSE, event_name.c_str())));
  ASSERT_NE(event.handle(), nullptr);

  command_line.AppendSwitchNative(kTestEventToSignal, event_name);
  EXPECT_TRUE(
      task_scheduler_->RegisterTask(kTaskName1, kTaskDescription1, command_line,
                                    TaskScheduler::TRIGGER_TYPE_NOW, false));
  EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout()));
  base::Time next_run_time;
  EXPECT_FALSE(task_scheduler_->GetNextTaskRunTime(kTaskName1, &next_run_time));
  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
}

TEST_F(TaskSchedulerTests, Hourly) {
  base::FilePath executable_path;
  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &executable_path));
  base::CommandLine command_line(
      executable_path.Append(kTestProcessExecutableName));

  base::Time now(base::Time::NowFromSystemTime());
  EXPECT_TRUE(
      task_scheduler_->RegisterTask(kTaskName1, kTaskDescription1, command_line,
                                    TaskScheduler::TRIGGER_TYPE_HOURLY, false));
  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName1));

  base::TimeDelta one_hour(base::TimeDelta::FromHours(1));
  base::TimeDelta one_minute(base::TimeDelta::FromMinutes(1));

  base::Time next_run_time;
  EXPECT_TRUE(task_scheduler_->GetNextTaskRunTime(kTaskName1, &next_run_time));
  EXPECT_LT(next_run_time, now + one_hour + one_minute);
  EXPECT_GT(next_run_time, now + one_hour - one_minute);

  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
  EXPECT_FALSE(task_scheduler_->IsTaskRegistered(kTaskName1));
  EXPECT_FALSE(task_scheduler_->GetNextTaskRunTime(kTaskName1, &next_run_time));
}

TEST_F(TaskSchedulerTests, EverySixHours) {
  base::FilePath executable_path;
  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &executable_path));
  base::CommandLine command_line(
      executable_path.Append(kTestProcessExecutableName));

  base::Time now(base::Time::NowFromSystemTime());
  EXPECT_TRUE(task_scheduler_->RegisterTask(
      kTaskName1, kTaskDescription1, command_line,
      TaskScheduler::TRIGGER_TYPE_EVERY_SIX_HOURS, false));
  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName1));

  base::TimeDelta six_hours(base::TimeDelta::FromHours(6));
  base::TimeDelta one_minute(base::TimeDelta::FromMinutes(1));

  base::Time next_run_time;
  EXPECT_TRUE(task_scheduler_->GetNextTaskRunTime(kTaskName1, &next_run_time));
  EXPECT_LT(next_run_time, now + six_hours + one_minute);
  EXPECT_GT(next_run_time, now + six_hours - one_minute);

  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
  EXPECT_FALSE(task_scheduler_->IsTaskRegistered(kTaskName1));
  EXPECT_FALSE(task_scheduler_->GetNextTaskRunTime(kTaskName1, &next_run_time));
}

TEST_F(TaskSchedulerTests, SetTaskEnabled) {
  base::FilePath executable_path;
  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &executable_path));
  base::CommandLine command_line(
      executable_path.Append(kTestProcessExecutableName));

  EXPECT_TRUE(
      task_scheduler_->RegisterTask(kTaskName1, kTaskDescription1, command_line,
                                    TaskScheduler::TRIGGER_TYPE_HOURLY, false));
  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName1));
  EXPECT_TRUE(task_scheduler_->IsTaskEnabled(kTaskName1));

  EXPECT_TRUE(task_scheduler_->SetTaskEnabled(kTaskName1, true));
  EXPECT_TRUE(task_scheduler_->IsTaskEnabled(kTaskName1));
  EXPECT_TRUE(task_scheduler_->SetTaskEnabled(kTaskName1, false));
  EXPECT_FALSE(task_scheduler_->IsTaskEnabled(kTaskName1));
  EXPECT_TRUE(task_scheduler_->SetTaskEnabled(kTaskName1, true));
  EXPECT_TRUE(task_scheduler_->IsTaskEnabled(kTaskName1));

  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
}

TEST_F(TaskSchedulerTests, GetTaskNameList) {
  base::FilePath executable_path;
  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &executable_path));
  base::CommandLine command_line(
      executable_path.Append(kTestProcessExecutableName));

  EXPECT_TRUE(
      task_scheduler_->RegisterTask(kTaskName1, kTaskDescription1, command_line,
                                    TaskScheduler::TRIGGER_TYPE_HOURLY, false));
  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName1));
  EXPECT_TRUE(
      task_scheduler_->RegisterTask(kTaskName2, kTaskDescription2, command_line,
                                    TaskScheduler::TRIGGER_TYPE_HOURLY, false));
  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName2));

  std::vector<base::string16> task_names;
  EXPECT_TRUE(task_scheduler_->GetTaskNameList(&task_names));
  EXPECT_TRUE(base::ContainsValue(task_names, kTaskName1));
  EXPECT_TRUE(base::ContainsValue(task_names, kTaskName2));

  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName2));
}

TEST_F(TaskSchedulerTests, GetTasksIncludesHidden) {
  base::FilePath executable_path;
  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &executable_path));
  base::CommandLine command_line(
      executable_path.Append(kTestProcessExecutableName));

  EXPECT_TRUE(
      task_scheduler_->RegisterTask(kTaskName1, kTaskDescription1, command_line,
                                    TaskScheduler::TRIGGER_TYPE_HOURLY, true));

  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName1));

  std::vector<base::string16> task_names;
  EXPECT_TRUE(task_scheduler_->GetTaskNameList(&task_names));
  EXPECT_TRUE(base::ContainsValue(task_names, kTaskName1));

  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
}

TEST_F(TaskSchedulerTests, GetTaskInfoExecActions) {
  base::FilePath executable_path;
  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &executable_path));
  base::CommandLine command_line1(
      executable_path.Append(kTestProcessExecutableName));

  EXPECT_TRUE(task_scheduler_->RegisterTask(
      kTaskName1, kTaskDescription1, command_line1,
      TaskScheduler::TRIGGER_TYPE_HOURLY, false));
  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName1));

  TaskScheduler::TaskInfo info;
  EXPECT_FALSE(task_scheduler_->GetTaskInfo(kTaskName2, &info));
  EXPECT_EQ(0UL, info.exec_actions.size());
  EXPECT_TRUE(task_scheduler_->GetTaskInfo(kTaskName1, &info));
  ASSERT_EQ(1UL, info.exec_actions.size());
  EXPECT_EQ(command_line1.GetProgram(), info.exec_actions[0].application_path);
  EXPECT_EQ(command_line1.GetArgumentsString(), info.exec_actions[0].arguments);

  base::CommandLine command_line2(
      executable_path.Append(kTestProcessExecutableName));
  command_line2.AppendSwitch(kTestSwitch);
  EXPECT_TRUE(task_scheduler_->RegisterTask(
      kTaskName2, kTaskDescription2, command_line2,
      TaskScheduler::TRIGGER_TYPE_HOURLY, false));
  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName2));

  // The |info| struct is re-used to ensure that new task information overwrites
  // the previous contents of the struct.
  EXPECT_TRUE(task_scheduler_->GetTaskInfo(kTaskName2, &info));
  ASSERT_EQ(1UL, info.exec_actions.size());
  EXPECT_EQ(command_line2.GetProgram(), info.exec_actions[0].application_path);
  EXPECT_EQ(command_line2.GetArgumentsString(), info.exec_actions[0].arguments);

  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName2));
}

TEST_F(TaskSchedulerTests, GetTaskInfoNameAndDescription) {
  base::FilePath executable_path;
  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &executable_path));
  base::CommandLine command_line1(
      executable_path.Append(kTestProcessExecutableName));

  EXPECT_TRUE(task_scheduler_->RegisterTask(
      kTaskName1, kTaskDescription1, command_line1,
      TaskScheduler::TRIGGER_TYPE_HOURLY, false));
  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName1));

  TaskScheduler::TaskInfo info;
  EXPECT_FALSE(task_scheduler_->GetTaskInfo(kTaskName2, &info));
  EXPECT_EQ(L"", info.description);
  EXPECT_EQ(L"", info.name);

  EXPECT_TRUE(task_scheduler_->GetTaskInfo(kTaskName1, &info));
  EXPECT_EQ(kTaskDescription1, info.description);
  EXPECT_EQ(kTaskName1, info.name);

  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
}

TEST_F(TaskSchedulerTests, GetTaskInfoLogonType) {
  base::FilePath executable_path;
  ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &executable_path));
  base::CommandLine command_line1(
      executable_path.Append(kTestProcessExecutableName));

  EXPECT_TRUE(task_scheduler_->RegisterTask(
      kTaskName1, kTaskDescription1, command_line1,
      TaskScheduler::TRIGGER_TYPE_HOURLY, false));
  EXPECT_TRUE(task_scheduler_->IsTaskRegistered(kTaskName1));

  TaskScheduler::TaskInfo info;
  EXPECT_FALSE(task_scheduler_->GetTaskInfo(kTaskName2, &info));
  EXPECT_EQ(0U, info.logon_type);
  EXPECT_TRUE(task_scheduler_->GetTaskInfo(kTaskName1, &info));
  EXPECT_TRUE(info.logon_type & TaskScheduler::LOGON_INTERACTIVE);
  EXPECT_FALSE(info.logon_type & TaskScheduler::LOGON_SERVICE);
  EXPECT_FALSE(info.logon_type & TaskScheduler::LOGON_S4U);

  EXPECT_TRUE(task_scheduler_->DeleteTask(kTaskName1));
}

}  // namespace chrome_cleaner
