// Copyright 2019 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 "dev-install/dev_install.h"

#include <unistd.h>

#include <istream>
#include <sstream>
#include <string>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

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

namespace dev_install {

namespace {

class DevInstallMock : public DevInstall {
 public:
  MOCK_METHOD(int, Exec, (const std::vector<const char*>&), (override));
  MOCK_METHOD(bool, IsDevMode, (), (const, override));
  MOCK_METHOD(bool,
              PromptUser,
              (std::istream&, const std::string&),
              (override));
  MOCK_METHOD(bool, ClearStateDir, (const base::FilePath&), (override));
  MOCK_METHOD(bool,
              InitializeStateDir,
              (const base::FilePath& dir),
              (override));
};

class DevInstallTest : public ::testing::Test {
 public:
  void SetUp() override {
    // Set the default to dev mode enabled.  Most tests want that.
    ON_CALL(dev_install_, IsDevMode()).WillByDefault(Return(true));

    // Ignore stateful setup for most tests.
    ON_CALL(dev_install_, InitializeStateDir(_)).WillByDefault(Return(true));

    // Most tests should run with a path that doesn't exist.
    dev_install_.SetStateDirForTest(base::FilePath("/.path-does-not-exist"));
  }

 protected:
  DevInstallMock dev_install_;
};

}  // namespace

// Check default run through.
TEST_F(DevInstallTest, Run) {
  EXPECT_CALL(dev_install_, Exec(_)).WillOnce(Return(1234));
  EXPECT_EQ(1234, dev_install_.Run());
}

// Systems not in dev mode should abort.
TEST_F(DevInstallTest, NonDevMode) {
  EXPECT_CALL(dev_install_, IsDevMode()).WillOnce(Return(false));
  EXPECT_CALL(dev_install_, ClearStateDir(_)).Times(0);
  EXPECT_CALL(dev_install_, Exec(_)).Times(0);
  EXPECT_EQ(2, dev_install_.Run());
}

// Check system has been initialized.
TEST_F(DevInstallTest, AlreadyInitialized) {
  dev_install_.SetStateDirForTest(base::FilePath("/"));
  EXPECT_CALL(dev_install_, Exec(_)).Times(0);
  ASSERT_EQ(4, dev_install_.Run());
}

// Check --reinstall passed.
TEST_F(DevInstallTest, RunReinstallWorked) {
  dev_install_.SetReinstallForTest(true);
  EXPECT_CALL(dev_install_, ClearStateDir(_)).WillOnce(Return(true));
  EXPECT_CALL(dev_install_, Exec(_)).WillOnce(Return(1234));
  ASSERT_EQ(1234, dev_install_.Run());
}

// Check when --reinstall is requested but clearing fails.
TEST_F(DevInstallTest, RunReinstallFails) {
  dev_install_.SetReinstallForTest(true);
  EXPECT_CALL(dev_install_, ClearStateDir(_)).WillOnce(Return(false));
  EXPECT_CALL(dev_install_, Exec(_)).Times(0);
  ASSERT_EQ(1, dev_install_.Run());
}

// Check --uninstall passed.
TEST_F(DevInstallTest, RunUninstall) {
  dev_install_.SetUninstallForTest(true);
  EXPECT_CALL(dev_install_, ClearStateDir(_)).WillOnce(Return(true));
  EXPECT_CALL(dev_install_, Exec(_)).Times(0);
  ASSERT_EQ(0, dev_install_.Run());
}

// Stateful setup failures.
TEST_F(DevInstallTest, StatefulSetupFailure) {
  EXPECT_CALL(dev_install_, InitializeStateDir(_)).WillOnce(Return(false));
  EXPECT_CALL(dev_install_, Exec(_)).Times(0);
  ASSERT_EQ(5, dev_install_.Run());
}

namespace {

class PromptUserTest : public ::testing::Test {
 protected:
  DevInstall dev_install_;
};

}  // namespace

// The --yes flag should pass w/out prompting the user.
TEST_F(PromptUserTest, Forced) {
  dev_install_.SetYesForTest(true);
  std::stringstream stream("");
  EXPECT_TRUE(dev_install_.PromptUser(stream, ""));
}

// EOF input should fail.
TEST_F(PromptUserTest, Eof) {
  std::stringstream stream("");
  EXPECT_FALSE(dev_install_.PromptUser(stream, ""));
}

// Default input (hitting enter) should fail.
TEST_F(PromptUserTest, Default) {
  std::stringstream stream("\n");
  EXPECT_FALSE(dev_install_.PromptUser(stream, ""));
}

// Entering "n" should fail.
TEST_F(PromptUserTest, No) {
  std::stringstream stream("n\n");
  EXPECT_FALSE(dev_install_.PromptUser(stream, ""));
}

// Entering "y" should pass.
TEST_F(PromptUserTest, Yes) {
  std::stringstream stream("y\n");
  EXPECT_TRUE(dev_install_.PromptUser(stream, ""));
}

namespace {

class DeletePathTest : public ::testing::Test {
 public:
  void SetUp() override {
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
    test_dir_ = scoped_temp_dir_.GetPath();
    dev_install_.SetStateDirForTest(test_dir_);
  }

 protected:
  DevInstall dev_install_;
  base::FilePath test_dir_;
  base::ScopedTempDir scoped_temp_dir_;
};

}  // namespace

// Check missing dir.
TEST_F(DeletePathTest, Missing) {
  struct stat st = {};
  EXPECT_TRUE(dev_install_.DeletePath(st, test_dir_.Append("foo")));
}

// Check deleting dir contents leaves the dir alone.
TEST_F(DeletePathTest, Empty) {
  struct stat st = {};
  EXPECT_TRUE(dev_install_.DeletePath(st, test_dir_));
  EXPECT_TRUE(base::PathExists(test_dir_));
}

// Check mounted deletion.
TEST_F(DeletePathTest, Mounted) {
  struct stat st = {};
  const base::FilePath subdir = test_dir_.Append("subdir");
  EXPECT_TRUE(base::CreateDirectory(subdir));
  EXPECT_FALSE(dev_install_.DeletePath(st, test_dir_));
  EXPECT_TRUE(base::PathExists(subdir));
}

// Check recursive deletion.
TEST_F(DeletePathTest, Works) {
  struct stat st;
  EXPECT_EQ(0, stat(test_dir_.value().c_str(), &st));

  EXPECT_EQ(3, base::WriteFile(test_dir_.Append("file"), "123", 3));
  EXPECT_EQ(0, symlink("x", test_dir_.Append("broken-sym").value().c_str()));
  EXPECT_EQ(0, symlink("file", test_dir_.Append("file-sym").value().c_str()));
  EXPECT_EQ(0, symlink(".", test_dir_.Append("dir-sym").value().c_str()));
  EXPECT_EQ(0, symlink("subdir", test_dir_.Append("dir-sym2").value().c_str()));
  const base::FilePath subdir = test_dir_.Append("subdir");
  EXPECT_TRUE(base::CreateDirectory(subdir));
  EXPECT_EQ(3, base::WriteFile(subdir.Append("file"), "123", 3));
  const base::FilePath subsubdir = test_dir_.Append("subdir");
  EXPECT_TRUE(base::CreateDirectory(subsubdir));
  EXPECT_EQ(3, base::WriteFile(subsubdir.Append("file"), "123", 3));

  EXPECT_TRUE(dev_install_.DeletePath(st, test_dir_));
  EXPECT_TRUE(base::PathExists(test_dir_));
  EXPECT_EQ(0, rmdir(test_dir_.value().c_str()));
}

namespace {

// We could mock out DeletePath, but it's easy to lightly validate it.
class ClearStateDirMock : public DevInstall {
 public:
  MOCK_METHOD(bool,
              PromptUser,
              (std::istream&, const std::string&),
              (override));
};

class ClearStateDirTest : public ::testing::Test {
 public:
  void SetUp() {
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
    test_dir_ = scoped_temp_dir_.GetPath();
  }

 protected:
  ClearStateDirMock dev_install_;
  base::FilePath test_dir_;
  base::ScopedTempDir scoped_temp_dir_;
};

}  // namespace

// Check user rejecting things.
TEST_F(ClearStateDirTest, Cancel) {
  EXPECT_CALL(dev_install_, PromptUser(_, _)).WillOnce(Return(false));
  const base::FilePath subdir = test_dir_.Append("subdir");
  ASSERT_TRUE(base::CreateDirectory(subdir));
  ASSERT_FALSE(dev_install_.ClearStateDir(test_dir_));
  ASSERT_TRUE(base::PathExists(subdir));
}

// Check missing dir is handled.
TEST_F(ClearStateDirTest, Missing) {
  EXPECT_CALL(dev_install_, PromptUser(_, _)).WillOnce(Return(true));
  ASSERT_TRUE(dev_install_.ClearStateDir(test_dir_.Append("subdir")));
  ASSERT_TRUE(base::PathExists(test_dir_));
}

// Check empty dir is handled.
TEST_F(ClearStateDirTest, Empty) {
  EXPECT_CALL(dev_install_, PromptUser(_, _)).WillOnce(Return(true));
  ASSERT_TRUE(dev_install_.ClearStateDir(test_dir_));
  ASSERT_TRUE(base::PathExists(test_dir_));
}

// Check dir with contents is cleared.
TEST_F(ClearStateDirTest, Works) {
  EXPECT_CALL(dev_install_, PromptUser(_, _)).WillOnce(Return(true));
  const base::FilePath subdir = test_dir_.Append("subdir");
  ASSERT_TRUE(base::CreateDirectory(subdir));
  ASSERT_TRUE(dev_install_.ClearStateDir(test_dir_));
  ASSERT_FALSE(base::PathExists(subdir));
}

namespace {

class InitializeStateDirTest : public ::testing::Test {
 public:
  void SetUp() {
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
    test_dir_ = scoped_temp_dir_.GetPath();
  }

 protected:
  DevInstall dev_install_;
  base::FilePath test_dir_;
  base::ScopedTempDir scoped_temp_dir_;
};

}  // namespace

// Check stateful is set up correctly.
TEST_F(InitializeStateDirTest, Works) {
  // Make sure we fully set things up.
  ASSERT_TRUE(dev_install_.InitializeStateDir(test_dir_));
  ASSERT_TRUE(base::IsLink(test_dir_.Append("usr")));
  ASSERT_TRUE(base::IsLink(test_dir_.Append("local")));
  ASSERT_TRUE(base::IsLink(test_dir_.Append("local")));
  const base::FilePath etc = test_dir_.Append("etc");
  ASSERT_TRUE(base::PathExists(etc));
  ASSERT_TRUE(base::IsLink(etc.Append("passwd")));
  ASSERT_TRUE(base::IsLink(etc.Append("group")));

  // Calling a second time should be fine.
  ASSERT_TRUE(dev_install_.InitializeStateDir(test_dir_));
}

// Check we handle errors gracefully.
TEST_F(InitializeStateDirTest, Fails) {
  // Create a broken /etc symlink.
  ASSERT_TRUE(
      base::CreateSymbolicLink(base::FilePath("foo"), test_dir_.Append("etc")));
  ASSERT_FALSE(dev_install_.InitializeStateDir(test_dir_));
}

namespace {

class LoadRuntimeSettingsTest : public ::testing::Test {
 public:
  void SetUp() {
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());
    test_dir_ = scoped_temp_dir_.GetPath();
  }

 protected:
  DevInstall dev_install_;
  base::FilePath test_dir_;
  base::ScopedTempDir scoped_temp_dir_;
};

}  // namespace

// Check loading state works.
TEST_F(LoadRuntimeSettingsTest, Works) {
  const base::FilePath lsb_release = test_dir_.Append("lsb-release");
  std::string data{
      "CHROMEOS_DEVSERVER=https://foo\n"
      "CHROMEOS_RELEASE_BOARD=betty\n"
      "CHROMEOS_RELEASE_CHROME_MILESTONE=79\n"
      "CHROMEOS_RELEASE_VERSION=100.10.1\n"};
  ASSERT_EQ(base::WriteFile(lsb_release, data.c_str(), data.size()),
            data.size());
  ASSERT_TRUE(dev_install_.LoadRuntimeSettings(lsb_release));
  ASSERT_EQ(dev_install_.GetDevserverUrlForTest(), "https://foo");
  ASSERT_EQ(dev_install_.GetBoardForTest(), "betty");
  ASSERT_EQ(dev_install_.GetBinhostVersionForTest(), "100.10.1");
}

// Check loading empty state works.
TEST_F(LoadRuntimeSettingsTest, Empty) {
  const base::FilePath lsb_release = test_dir_.Append("lsb-release");
  std::string data{""};
  ASSERT_EQ(base::WriteFile(lsb_release, data.c_str(), data.size()),
            data.size());
  ASSERT_TRUE(dev_install_.LoadRuntimeSettings(lsb_release));
}

// Check loading state doesn't abort with missing file.
TEST_F(LoadRuntimeSettingsTest, Missing) {
  ASSERT_TRUE(dev_install_.LoadRuntimeSettings(test_dir_.Append("asdf")));
}

}  // namespace dev_install
