// Copyright 2017 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.

// How to build and run the tests: see arc_setup_util_unittest.cc

#include "arc/setup/arc_setup.h"

#include <set>

#include <base/command_line.h>
#include <base/environment.h>
#include <base/files/file_path.h>
#include <base/files/scoped_temp_dir.h>
#include <base/macros.h>
#include <base/stl_util.h>
#include <gtest/gtest.h>

#include "arc/setup/arc_setup_util.h"

namespace arc {

namespace {

class MockArcMounter : public ArcMounter {
 public:
  MockArcMounter() = default;
  MockArcMounter(const MockArcMounter&) = delete;
  MockArcMounter& operator=(const MockArcMounter&) = delete;

  ~MockArcMounter() override = default;

  bool Mount(const std::string& source,
             const base::FilePath& target,
             const char* filesystem_type,
             unsigned long mount_flags,  // NOLINT(runtime/int)
             const char* data) override {
    mount_points_.insert(target.value());
    return true;
  }

  bool Remount(const base::FilePath& target_directory,
               unsigned long mount_flags,  // NOLINT(runtime/int)
               const char* data) override {
    return true;
  }

  bool LoopMount(const std::string& source,
                 const base::FilePath& target,
                 unsigned long mount_flags) override {  // NOLINT(runtime/int)
    loop_mount_points_.insert(target.value());
    return true;
  }

  bool BindMount(const base::FilePath& old_path,
                 const base::FilePath& new_path) override {
    mount_points_.insert(new_path.value());
    return true;
  }

  bool SharedMount(const base::FilePath& path) override { return true; }

  bool Umount(const base::FilePath& path) override {
    auto it = mount_points_.find(path.value());
    if (it == mount_points_.end())
      return false;
    mount_points_.erase(it);
    return true;
  }

  bool UmountIfExists(const base::FilePath& path) override {
    Umount(path);
    // If mount does not exist, succeed anyway.
    return true;
  }

  bool LoopUmount(const base::FilePath& path) override {
    auto it = loop_mount_points_.find(path.value());
    if (it == loop_mount_points_.end())
      return false;
    loop_mount_points_.erase(it);
    return true;
  }

  bool LoopUmountIfExists(const base::FilePath& path) override {
    LoopUmount(path);
    // If loop mount does not exist, succeed anyway.
    return true;
  }

  std::multiset<std::string> mount_points_;
  std::multiset<std::string> loop_mount_points_;
};

}  // namespace

// Tests MockArcMounter itself.
TEST(ArcSetup, TestMockArcMounter) {
  MockArcMounter mounter;
  EXPECT_TRUE(mounter.BindMount(base::FilePath("/a"), base::FilePath("/b")));
  EXPECT_TRUE(mounter.BindMount(base::FilePath("/c"), base::FilePath("/b")));
  EXPECT_EQ(2U, mounter.mount_points_.size());
  EXPECT_FALSE(mounter.Umount(base::FilePath("/x")));  // unknown path
  EXPECT_TRUE(mounter.Umount(base::FilePath("/b")));
  EXPECT_EQ(1U, mounter.mount_points_.size());
  EXPECT_TRUE(mounter.Umount(base::FilePath("/b")));
  EXPECT_TRUE(mounter.mount_points_.empty());
  EXPECT_FALSE(mounter.Umount(base::FilePath("/b")));  // now /b is unknown

  // Do the same for loop.
  EXPECT_TRUE(mounter.LoopMount("/a.img", base::FilePath("/d"), 0U));
  EXPECT_TRUE(mounter.LoopMount("/c.img", base::FilePath("/d"), 0U));
  EXPECT_EQ(2U, mounter.loop_mount_points_.size());
  EXPECT_FALSE(mounter.LoopUmount(base::FilePath("/x")));  // unknown path
  EXPECT_TRUE(mounter.LoopUmount(base::FilePath("/d")));
  EXPECT_EQ(1U, mounter.loop_mount_points_.size());
  EXPECT_TRUE(mounter.LoopUmount(base::FilePath("/d")));
  EXPECT_TRUE(mounter.loop_mount_points_.empty());
  EXPECT_FALSE(mounter.LoopUmount(base::FilePath("/d")));  // now /d is unknown
}

// Tests --mode=onetime-setup and --mode=onetime-stop.
TEST(ArcSetup, TestOnetimeSetupStop) {
  const char* argv[] = {"test", "--mode=onetime-setup"};
  base::CommandLine::ForCurrentProcess()->InitFromArgv(base::size(argv), argv);
  std::unique_ptr<base::Environment> env(base::Environment::Create());

  // ArcSetup needs some config variables.
  base::ScopedTempDir temp_directory;
  ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
  const base::FilePath config_json(temp_directory.GetPath().Append("json"));
  ASSERT_TRUE(WriteToFile(config_json, 0700, "{\"WRITABLE_MOUNT\": false}"));

  ArcSetup setup(Mode::ONETIME_SETUP, config_json);
  setup.set_arc_mounter_for_testing(std::make_unique<MockArcMounter>());

  // Do the one-time setup and confirm both loop and non-loop mount points are
  // not empty.
  setup.MountOnOnetimeSetupForTesting();
  // Check that |loop_mount_points_| has system and vendor images etc.
  EXPECT_FALSE(
      static_cast<const MockArcMounter*>(setup.arc_mounter_for_testing())
          ->loop_mount_points_.empty());

  // Do the one-time stop and confirm all mount points are cleaned up.
  setup.UnmountOnOnetimeStopForTesting();
  EXPECT_TRUE(
      static_cast<const MockArcMounter*>(setup.arc_mounter_for_testing())
          ->mount_points_.empty());
  EXPECT_TRUE(
      static_cast<const MockArcMounter*>(setup.arc_mounter_for_testing())
          ->loop_mount_points_.empty());
}

}  // namespace arc
