// Copyright (c) 2012 The Chromium OS 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 "login_manager/browser_job.h"

#include <stdint.h>
#include <unistd.h>

#include <algorithm>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <base/command_line.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "login_manager/mock_file_checker.h"
#include "login_manager/mock_metrics.h"
#include "login_manager/mock_system_utils.h"

namespace login_manager {

using ::testing::AnyNumber;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::_;

class BrowserJobTest : public ::testing::Test {
 public:
  BrowserJobTest() {}

  virtual ~BrowserJobTest() {}

  void SetUp() override;

 protected:
  static const char* kArgv[];
  static const char kUser[];
  static const char kHash[];

  void ExpectArgsToContainFlag(const std::vector<std::string>& argv,
                               const char name[],
                               const char value[]) {
    std::vector<std::string>::const_iterator user_flag = std::find(
        argv.begin(), argv.end(), base::StringPrintf("%s%s", name, value));
    EXPECT_NE(user_flag, argv.end()) << "argv should contain " << name << value;
  }

  void ExpectArgsNotToContainFlag(const std::vector<std::string>& argv,
                                  const char name[],
                                  const char value[]) {
    std::vector<std::string>::const_iterator user_flag = std::find(
        argv.begin(), argv.end(), base::StringPrintf("%s%s", name, value));
    EXPECT_EQ(user_flag, argv.end()) << "argv shouldn't contain " << name
                                     << value;
  }

  void ExpectArgsToContainAll(const std::vector<std::string>& argv,
                              const std::vector<std::string>& contained) {
    std::set<std::string> argv_set(argv.begin(), argv.end());
    for (std::vector<std::string>::const_iterator it = contained.begin();
         it != contained.end();
         ++it) {
      EXPECT_EQ(argv_set.count(*it), 1) << "argv should contain " << *it;
    }
  }

  std::map<std::string, std::string> env_;
  std::vector<std::string> argv_;
  MockFileChecker checker_;
  MockMetrics metrics_;
  MockSystemUtils utils_;
  std::unique_ptr<BrowserJob> job_;

 private:
  DISALLOW_COPY_AND_ASSIGN(BrowserJobTest);
};

// Default argument list for a job to use in mostly all test cases.
const char* BrowserJobTest::kArgv[] = {"zero", "one", "two"};

// Normal username to test session for.
const char BrowserJobTest::kUser[] = "test@gmail.com";
const char BrowserJobTest::kHash[] = "fake_hash";

void BrowserJobTest::SetUp() {
  argv_ =
      std::vector<std::string>(kArgv, kArgv + arraysize(BrowserJobTest::kArgv));
  job_.reset(
      new BrowserJob(argv_, env_, getuid(), &checker_, &metrics_, &utils_));
}

TEST_F(BrowserJobTest, InitializationTest) {
  EXPECT_FALSE(job_->removed_login_manager_flag_);
  std::vector<std::string> job_args = job_->ExportArgv();
  ASSERT_EQ(argv_.size(), job_args.size());
  ExpectArgsToContainAll(job_args, argv_);
}

TEST_F(BrowserJobTest, WaitAndAbort) {
  pid_t kDummyPid = 4;
  EXPECT_CALL(utils_, fork()).WillOnce(Return(kDummyPid));
  EXPECT_CALL(utils_, kill(-kDummyPid, _, SIGABRT)).Times(1);
  EXPECT_CALL(utils_, time(NULL)).WillRepeatedly(Return(0));
  EXPECT_CALL(utils_, ProcessGroupIsGone(kDummyPid, _)).WillOnce(Return(false));

  EXPECT_CALL(metrics_, HasRecordedChromeExec()).WillRepeatedly(Return(false));
  EXPECT_CALL(metrics_, RecordStats(_)).Times(AnyNumber());

  ASSERT_TRUE(job_->RunInBackground());
  job_->WaitAndAbort(base::TimeDelta::FromSeconds(3));
}

TEST_F(BrowserJobTest, WaitAndAbort_AlreadyGone) {
  pid_t kDummyPid = 4;
  EXPECT_CALL(utils_, fork()).WillOnce(Return(kDummyPid));
  EXPECT_CALL(utils_, time(NULL)).WillRepeatedly(Return(0));
  EXPECT_CALL(utils_, ProcessGroupIsGone(kDummyPid, _)).WillOnce(Return(true));

  EXPECT_CALL(metrics_, HasRecordedChromeExec()).WillRepeatedly(Return(false));
  EXPECT_CALL(metrics_, RecordStats(_)).Times(AnyNumber());

  ASSERT_TRUE(job_->RunInBackground());
  job_->WaitAndAbort(base::TimeDelta::FromSeconds(3));
}

TEST_F(BrowserJobTest, ShouldStopTest) {
  EXPECT_CALL(utils_, time(NULL))
      .WillRepeatedly(Return(BrowserJob::kRestartWindowSeconds));
  for (uint32_t i = 0; i < BrowserJob::kRestartTries - 1; ++i)
    job_->RecordTime();
  // We haven't yet saturated the list of start times, so...
  EXPECT_FALSE(job_->ShouldStop());

  // Go ahead and saturate.
  job_->RecordTime();
  EXPECT_NE(0, job_->start_times_.front());
  EXPECT_TRUE(job_->ShouldStop());
}

TEST_F(BrowserJobTest, ShouldNotStopTest) {
  EXPECT_CALL(utils_, time(NULL))
      .WillOnce(Return(BrowserJob::kRestartWindowSeconds))
      .WillOnce(Return(3 * BrowserJob::kRestartWindowSeconds));
  job_->RecordTime();
  EXPECT_FALSE(job_->ShouldStop());
}

TEST_F(BrowserJobTest, ShouldNotRunTest) {
  EXPECT_CALL(checker_, exists()).WillRepeatedly(Return(true));
  EXPECT_FALSE(job_->ShouldRunBrowser());
}

TEST_F(BrowserJobTest, ShouldRunTest) {
  EXPECT_CALL(checker_, exists()).WillRepeatedly(Return(false));
  EXPECT_TRUE(job_->ShouldRunBrowser());
}

TEST_F(BrowserJobTest, NullFileCheckerTest) {
  BrowserJob job(argv_, env_, 1, NULL, &metrics_, &utils_);
  EXPECT_TRUE(job.ShouldRunBrowser());
}

// On the job's first run, it should have a one-time-flag.  That
// should get cleared and not used again.
TEST_F(BrowserJobTest, OneTimeBootFlags) {
  EXPECT_CALL(utils_, fork()).WillRepeatedly(Return(1));
  EXPECT_CALL(utils_, time(NULL)).WillRepeatedly(Return(0));

  EXPECT_CALL(metrics_, HasRecordedChromeExec())
      .WillOnce(Return(false))
      .WillOnce(Return(true));
  EXPECT_CALL(metrics_, RecordStats(StrEq(("chrome-exec")))).Times(2);

  ASSERT_TRUE(job_->RunInBackground());
  ExpectArgsToContainFlag(
      job_->ExportArgv(), BrowserJob::kFirstExecAfterBootFlag, "");

  ASSERT_TRUE(job_->RunInBackground());
  ExpectArgsNotToContainFlag(
      job_->ExportArgv(), BrowserJob::kFirstExecAfterBootFlag, "");
}

TEST_F(BrowserJobTest, RunBrowserTermMessage) {
  pid_t kDummyPid = 4;
  int signal = SIGKILL;
  EXPECT_CALL(utils_, fork()).WillOnce(Return(kDummyPid));
  EXPECT_CALL(utils_, kill(kDummyPid, _, signal)).Times(1);
  EXPECT_CALL(utils_, time(NULL)).WillRepeatedly(Return(0));

  EXPECT_CALL(metrics_, HasRecordedChromeExec()).WillRepeatedly(Return(false));
  EXPECT_CALL(metrics_, RecordStats(_)).Times(AnyNumber());

  std::string term_message("killdya");
  ASSERT_TRUE(job_->RunInBackground());
  job_->Kill(signal, term_message);
}

TEST_F(BrowserJobTest, StartStopSessionTest) {
  job_->StartSession(kUser, kHash);

  std::vector<std::string> job_args = job_->ExportArgv();
  ASSERT_LT(argv_.size(), job_args.size());
  ExpectArgsToContainAll(job_args, argv_);
  ExpectArgsToContainFlag(job_args, BrowserJob::kLoginUserFlag, kUser);
  ExpectArgsToContainFlag(job_args, BrowserJob::kLoginProfileFlag, kHash);

  // Should remove login user flag.
  job_->StopSession();
  job_args = job_->ExportArgv();
  ASSERT_EQ(argv_.size(), job_args.size());
  ExpectArgsToContainAll(job_args, argv_);
}

TEST_F(BrowserJobTest, StartStopMultiSessionTest) {
  BrowserJob job(argv_, env_, 1, &checker_, &metrics_, &utils_);
  job.StartSession(kUser, kHash);

  std::vector<std::string> job_args = job.ExportArgv();
  ASSERT_EQ(argv_.size() + 2, job_args.size());
  ExpectArgsToContainAll(job_args, argv_);
  ExpectArgsToContainFlag(job_args, BrowserJob::kLoginUserFlag, kUser);
  ExpectArgsToContainFlag(job_args, BrowserJob::kLoginProfileFlag, kHash);

  // Start another session, expect the args to be unchanged.
  job.StartSession(kUser, kHash);
  job_args = job.ExportArgv();
  ASSERT_EQ(argv_.size() + 2, job_args.size());
  ExpectArgsToContainAll(job_args, argv_);
  ExpectArgsToContainFlag(job_args, BrowserJob::kLoginUserFlag, kUser);
  ExpectArgsToContainFlag(job_args, BrowserJob::kLoginProfileFlag, kHash);

  // Should remove login user and login profile flags.
  job.StopSession();
  job_args = job.ExportArgv();
  ASSERT_EQ(argv_.size(), job_args.size());
  ExpectArgsToContainAll(job_args, argv_);
}

TEST_F(BrowserJobTest, StartStopSessionFromLoginTest) {
  const char* kArgvWithLoginFlag[] = {"zero", "one", "two", "--login-manager"};
  std::vector<std::string> argv(
      kArgvWithLoginFlag, kArgvWithLoginFlag + arraysize(kArgvWithLoginFlag));
  BrowserJob job(argv, env_, 1, &checker_, &metrics_, &utils_);

  job.StartSession(kUser, kHash);

  std::vector<std::string> job_args = job.ExportArgv();
  ASSERT_EQ(argv.size() + 1, job_args.size());
  ExpectArgsToContainAll(
      job_args, std::vector<std::string>(argv.begin(), argv.end() - 1));
  ExpectArgsToContainFlag(job_args, BrowserJob::kLoginUserFlag, kUser);

  // Should remove login user/hash flags and append --login-manager flag back.
  job.StopSession();
  job_args = job.ExportArgv();
  ASSERT_EQ(argv.size(), job_args.size());
  ExpectArgsToContainAll(job_args, argv);
}

TEST_F(BrowserJobTest, SetArguments) {
  const char* kNewArgs[] = {"--ichi", "--ni dfs", "--san"};
  std::vector<std::string> new_args(kNewArgs, kNewArgs + arraysize(kNewArgs));
  job_->SetArguments(new_args);

  std::vector<std::string> job_args = job_->ExportArgv();
  ASSERT_EQ(new_args.size(), job_args.size());
  EXPECT_EQ(kArgv[0], job_args[0]);
  for (size_t i = 1; i < arraysize(kNewArgs); ++i) {
    EXPECT_EQ(kNewArgs[i], job_args[i]);
  }

  job_->StartSession(kUser, kHash);
  job_args = job_->ExportArgv();
  ExpectArgsToContainFlag(job_args, BrowserJob::kLoginUserFlag, kUser);
}

TEST_F(BrowserJobTest, SetExtraArguments) {
  const char* kExtraArgs[] = {"--ichi", "--ni", "--san"};
  std::vector<std::string> extra_args(kExtraArgs,
                                      kExtraArgs + arraysize(kExtraArgs));
  job_->SetExtraArguments(extra_args);

  std::vector<std::string> job_args = job_->ExportArgv();
  ExpectArgsToContainAll(job_args, argv_);
  ExpectArgsToContainAll(job_args, extra_args);
}

TEST_F(BrowserJobTest, ExportArgv) {
  std::vector<std::string> argv(kArgv, kArgv + arraysize(kArgv));
  BrowserJob job(argv, env_, -1, &checker_, &metrics_, &utils_);

  const char* kExtraArgs[] = {"--ichi", "--ni", "--san"};
  std::vector<std::string> extra_args(kExtraArgs,
                                      kExtraArgs + arraysize(kExtraArgs));
  argv.insert(argv.end(), extra_args.begin(), extra_args.end());
  job.SetExtraArguments(extra_args);
  EXPECT_EQ(argv, job.ExportArgv());
}

TEST_F(BrowserJobTest, CombineVModuleArgs) {
  const char* kArg1 = "--first";
  const char* kArg2 = "--second_arg=blah";
  const char* kArg3 = "--third_arg=5";
  const char* kArg4 = "--last_arg";

  {
    // A testcase with 3 --vmodule flags.
    const char* kVmodule1 = "--vmodule=file1=1,file2=2";
    const char* kVmodule2 = "--vmodule=file3=3,file4=4,file5=5";
    const char* kVmodule3 = "--vmodule=file6=6";

    const char* kMultipleVmoduleArgs[] = {
      kArg1, kVmodule1, kArg2, kArg3, kVmodule2, kVmodule3, kArg4
    };

    std::vector<std::string> argv(
        kMultipleVmoduleArgs,
        kMultipleVmoduleArgs + arraysize(kMultipleVmoduleArgs));
    BrowserJob job(argv, env_, -1, &checker_, &metrics_, &utils_);

    const char* kCombinedVmodule =
        "--vmodule=file1=1,file2=2,file3=3,file4=4,file5=5,file6=6";

    auto job_argv = job.ExportArgv();
    ASSERT_EQ(5, job_argv.size());
    EXPECT_EQ(kArg1, job_argv[0]);
    EXPECT_EQ(kArg2, job_argv[1]);
    EXPECT_EQ(kArg3, job_argv[2]);
    EXPECT_EQ(kArg4, job_argv[3]);
    EXPECT_EQ(kCombinedVmodule, job_argv[4]);
  }

  {
    // A testcase with no --vmodule flag.
    const char* kNoVmoduleArgs[] = {
      kArg1, kArg2, kArg3, kArg4
    };
    std::vector<std::string> argv(
        kNoVmoduleArgs, kNoVmoduleArgs + arraysize(kNoVmoduleArgs));

    BrowserJob job(argv, env_, -1, &checker_, &metrics_, &utils_);

    auto job_argv = job.ExportArgv();
    ASSERT_EQ(4, job_argv.size());
    EXPECT_EQ(kArg1, job_argv[0]);
    EXPECT_EQ(kArg2, job_argv[1]);
    EXPECT_EQ(kArg3, job_argv[2]);
    EXPECT_EQ(kArg4, job_argv[3]);
  }
}

}  // namespace login_manager
