// 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() 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_;

 private:
  DISALLOW_COPY_AND_ASSIGN(MockArcMounter);
};

}  // 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
