// 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 "cros-disks/platform.h"

#include <sys/types.h>
#include <unistd.h>

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

using base::FilePath;
using std::set;
using std::string;

namespace cros_disks {

class PlatformTest : public ::testing::Test {
 public:
  // Returns true if |path| is owned by |user_id| and |group_id|.
  static bool CheckOwnership(const string& path,
                             uid_t user_id, gid_t group_id) {
    struct stat buffer;
    if (stat(path.c_str(), &buffer) != 0)
      return false;
    return buffer.st_uid == user_id && buffer.st_gid == group_id;
  }

  // Returns true if |path| has its permissions set to |mode|.
  static bool CheckPermissions(const string& path, mode_t mode) {
    struct stat buffer;
    if (stat(path.c_str(), &buffer) != 0)
      return false;
    return (buffer.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) == mode;
  }

 protected:
  Platform platform_;
};

TEST_F(PlatformTest, GetRealPath) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath subdir_path;
  ASSERT_TRUE(
      base::CreateTemporaryDirInDir(temp_dir.path(), "test", &subdir_path));
  FilePath file_path;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(subdir_path, &file_path));
  FilePath file_symlink = temp_dir.path().Append("file_symlink");
  ASSERT_TRUE(base::CreateSymbolicLink(file_path, file_symlink));
  FilePath subdir_symlink = temp_dir.path().Append("subdir_symlink");
  ASSERT_TRUE(base::CreateSymbolicLink(subdir_path, subdir_symlink));

  string real_path;
  EXPECT_FALSE(platform_.GetRealPath("", &real_path));
  EXPECT_FALSE(platform_.GetRealPath("/nonexistent", &real_path));

  EXPECT_TRUE(platform_.GetRealPath(temp_dir.path().value(), &real_path));
  EXPECT_EQ(temp_dir.path().value(), real_path);

  EXPECT_TRUE(platform_.GetRealPath(file_path.value(), &real_path));
  EXPECT_EQ(file_path.value(), real_path);

  EXPECT_TRUE(platform_.GetRealPath(file_symlink.value(), &real_path));
  EXPECT_EQ(file_path.value(), real_path);

  EXPECT_TRUE(platform_.GetRealPath(subdir_symlink.value(), &real_path));
  EXPECT_EQ(subdir_path.value(), real_path);

  FilePath relative_path = subdir_path.Append("..");
  EXPECT_TRUE(platform_.GetRealPath(relative_path.value(), &real_path));
  EXPECT_EQ(temp_dir.path().value(), real_path);

  relative_path = subdir_path.Append("..")
                      .Append(subdir_path.BaseName())
                      .Append(file_path.BaseName());
  EXPECT_TRUE(platform_.GetRealPath(relative_path.value(), &real_path));
  EXPECT_EQ(file_path.value(), real_path);

  relative_path = subdir_path.Append("..")
                      .Append(subdir_symlink.BaseName())
                      .Append(file_path.BaseName());
  EXPECT_TRUE(platform_.GetRealPath(relative_path.value(), &real_path));
  EXPECT_EQ(file_path.value(), real_path);
}

TEST_F(PlatformTest, CreateDirectory) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Nonexistent directory
  FilePath new_dir = temp_dir.path().Append("test");
  string path = new_dir.value();
  EXPECT_TRUE(platform_.CreateDirectory(path));

  // Existent but empty directory
  EXPECT_TRUE(platform_.CreateDirectory(path));

  // Existent and non-empty directory
  FilePath temp_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(new_dir, &temp_file));
  EXPECT_TRUE(platform_.CreateDirectory(path));
}

TEST_F(PlatformTest, CreateOrReuseEmptyDirectory) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Nonexistent directory
  FilePath new_dir = temp_dir.path().Append("test");
  string path = new_dir.value();
  EXPECT_TRUE(platform_.CreateOrReuseEmptyDirectory(path));

  // Existent but empty directory
  EXPECT_TRUE(platform_.CreateOrReuseEmptyDirectory(path));

  // Existent and non-empty directory
  FilePath temp_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(new_dir, &temp_file));
  EXPECT_FALSE(platform_.CreateOrReuseEmptyDirectory(path));
}

TEST_F(PlatformTest, CreateOrReuseEmptyDirectoryWithFallback) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  set<string> reserved_paths;

  // Nonexistent directory
  FilePath new_dir = temp_dir.path().Append("test1");
  string path = new_dir.value();
  EXPECT_TRUE(platform_.CreateOrReuseEmptyDirectoryWithFallback(
      &path, 10, reserved_paths));
  EXPECT_EQ(new_dir.value(), path);

  // Existent but empty directory
  path = new_dir.value();
  EXPECT_TRUE(platform_.CreateOrReuseEmptyDirectoryWithFallback(
      &path, 10, reserved_paths));
  EXPECT_EQ(new_dir.value(), path);

  // Existent and non-empty directory
  FilePath temp_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(new_dir, &temp_file));
  path = new_dir.value();
  EXPECT_FALSE(platform_.CreateOrReuseEmptyDirectoryWithFallback(
      &path, 0, reserved_paths));
  EXPECT_TRUE(platform_.CreateOrReuseEmptyDirectoryWithFallback(
      &path, 1, reserved_paths));
  FilePath new_dir1 = temp_dir.path().Append("test1 (1)");
  EXPECT_EQ(new_dir1.value(), path);

  ASSERT_TRUE(base::CreateTemporaryFileInDir(new_dir1, &temp_file));
  path = new_dir.value();
  EXPECT_FALSE(platform_.CreateOrReuseEmptyDirectoryWithFallback(
      &path, 0, reserved_paths));
  EXPECT_FALSE(platform_.CreateOrReuseEmptyDirectoryWithFallback(
      &path, 1, reserved_paths));
  EXPECT_TRUE(platform_.CreateOrReuseEmptyDirectoryWithFallback(
      &path, 2, reserved_paths));
  FilePath new_dir2 = temp_dir.path().Append("test1 (2)");
  EXPECT_EQ(new_dir2.value(), path);
}

TEST_F(PlatformTest, CreateOrReuseEmptyDirectoryWithFallbackAndReservedPaths) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  set<string> reserved_paths;

  FilePath new_dir = temp_dir.path().Append("test");
  string path = new_dir.value();
  reserved_paths.insert(path);
  EXPECT_FALSE(platform_.CreateOrReuseEmptyDirectoryWithFallback(
      &path, 0, reserved_paths));
  EXPECT_EQ(new_dir.value(), path);

  reserved_paths.insert(temp_dir.path().Append("test 1").value());
  reserved_paths.insert(temp_dir.path().Append("test 2").value());
  EXPECT_FALSE(platform_.CreateOrReuseEmptyDirectoryWithFallback(
      &path, 2, reserved_paths));
  EXPECT_EQ(new_dir.value(), path);

  FilePath expected_dir = temp_dir.path().Append("test 3");
  EXPECT_TRUE(platform_.CreateOrReuseEmptyDirectoryWithFallback(
      &path, 3, reserved_paths));
  EXPECT_EQ(expected_dir.value(), path);
}

TEST_F(PlatformTest, GetDirectoryFallbackName) {
  EXPECT_EQ("test 1", platform_.GetDirectoryFallbackName("test", 1));
  EXPECT_EQ("test1 (1)", platform_.GetDirectoryFallbackName("test1", 1));
}

TEST_F(PlatformTest, GetGroupIdOfRoot) {
  gid_t group_id;
  EXPECT_TRUE(platform_.GetGroupId("root", &group_id));
  EXPECT_EQ(0, group_id);
}

TEST_F(PlatformTest, GetGroupIdOfNonExistentGroup) {
  gid_t group_id;
  EXPECT_FALSE(platform_.GetGroupId("nonexistent-group", &group_id));
}

TEST_F(PlatformTest, GetUserAndGroupIdOfRoot) {
  uid_t user_id;
  gid_t group_id;
  EXPECT_TRUE(platform_.GetUserAndGroupId("root", &user_id, &group_id));
  EXPECT_EQ(0, user_id);
  EXPECT_EQ(0, group_id);
}

TEST_F(PlatformTest, GetUserAndGroupIdOfNonExistentUser) {
  uid_t user_id;
  gid_t group_id;
  EXPECT_FALSE(platform_.GetUserAndGroupId("nonexistent-user",
                                           &user_id, &group_id));
}

TEST_F(PlatformTest, GetOwnershipOfDirectory) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  string path = temp_dir.path().value();

  uid_t user_id;
  gid_t group_id;
  EXPECT_TRUE(platform_.GetOwnership(path, &user_id, &group_id));
  EXPECT_EQ(getuid(), user_id);
  EXPECT_EQ(getgid(), group_id);
}

TEST_F(PlatformTest, GetOwnershipOfFile) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath temp_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &temp_file));
  string path = temp_file.value();

  uid_t user_id;
  gid_t group_id;
  EXPECT_TRUE(platform_.GetOwnership(path, &user_id, &group_id));
  EXPECT_EQ(getuid(), user_id);
  EXPECT_EQ(getgid(), group_id);
}

TEST_F(PlatformTest, GetOwnershipOfSymbolicLink) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath temp_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &temp_file));
  string file_path = temp_file.value();
  string symlink_path = file_path + "-symlink";
  FilePath temp_symlink(symlink_path);
  ASSERT_TRUE(base::CreateSymbolicLink(temp_file, temp_symlink));

  uid_t user_id;
  gid_t group_id;
  EXPECT_TRUE(platform_.GetOwnership(symlink_path, &user_id, &group_id));
  EXPECT_EQ(getuid(), user_id);
  EXPECT_EQ(getgid(), group_id);
}

TEST_F(PlatformTest, GetOwnershipOfNonexistentPath) {
  uid_t user_id;
  gid_t group_id;
  EXPECT_FALSE(platform_.GetOwnership("/nonexistent-path",
                                      &user_id, &group_id));
}

TEST_F(PlatformTest, GetPermissionsOfDirectory) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  string path = temp_dir.path().value();

  mode_t mode = 0;
  EXPECT_TRUE(platform_.GetPermissions(path, &mode));
  mode_t expected_mode = (mode & ~S_IRWXG & ~S_IRWXO) | S_IRWXU;
  EXPECT_TRUE(platform_.SetPermissions(path, expected_mode));
  EXPECT_TRUE(platform_.GetPermissions(path, &mode));
  EXPECT_EQ(expected_mode, mode);

  mode = 0;
  expected_mode |= S_IRWXG;
  EXPECT_TRUE(platform_.SetPermissions(path, expected_mode));
  EXPECT_TRUE(platform_.GetPermissions(path, &mode));
  EXPECT_EQ(expected_mode, mode);
}

TEST_F(PlatformTest, GetPermissionsOfFile) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath temp_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &temp_file));
  string path = temp_file.value();

  mode_t mode = 0;
  EXPECT_TRUE(platform_.GetPermissions(path, &mode));
  mode_t expected_mode = (mode & ~S_IRWXG & ~S_IRWXO) | S_IRWXU;
  EXPECT_TRUE(platform_.SetPermissions(path, expected_mode));
  EXPECT_TRUE(platform_.GetPermissions(path, &mode));
  EXPECT_EQ(expected_mode, mode);

  mode = 0;
  expected_mode |= S_IRWXG;
  EXPECT_TRUE(platform_.SetPermissions(path, expected_mode));
  EXPECT_TRUE(platform_.GetPermissions(path, &mode));
  EXPECT_EQ(expected_mode, mode);
}

TEST_F(PlatformTest, GetPermissionsOfSymbolicLink) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  FilePath temp_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.path(), &temp_file));
  string file_path = temp_file.value();
  string symlink_path = file_path + "-symlink";
  FilePath temp_symlink(symlink_path);
  ASSERT_TRUE(base::CreateSymbolicLink(temp_file, temp_symlink));

  mode_t mode = 0;
  EXPECT_TRUE(platform_.GetPermissions(file_path, &mode));
  mode_t expected_mode = (mode & ~S_IRWXG & ~S_IRWXO) | S_IRWXU;
  EXPECT_TRUE(platform_.SetPermissions(file_path, expected_mode));
  EXPECT_TRUE(platform_.GetPermissions(symlink_path, &mode));
  EXPECT_EQ(expected_mode, mode);

  mode = 0;
  expected_mode |= S_IRWXG;
  EXPECT_TRUE(platform_.SetPermissions(file_path, expected_mode));
  EXPECT_TRUE(platform_.GetPermissions(symlink_path, &mode));
  EXPECT_EQ(expected_mode, mode);
}

TEST_F(PlatformTest, GetPermissionsOfNonexistentPath) {
  mode_t mode;
  EXPECT_FALSE(platform_.GetPermissions("/nonexistent-path", &mode));
}

TEST_F(PlatformTest, RemoveEmptyDirectory) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  // Nonexistent directory
  FilePath new_dir = temp_dir.path().Append("test");
  string path = new_dir.value();
  EXPECT_FALSE(platform_.RemoveEmptyDirectory(path));

  // Existent but empty directory
  EXPECT_TRUE(platform_.CreateOrReuseEmptyDirectory(path));
  EXPECT_TRUE(platform_.RemoveEmptyDirectory(path));

  // Existent and non-empty directory
  EXPECT_TRUE(platform_.CreateOrReuseEmptyDirectory(path));
  FilePath temp_file;
  ASSERT_TRUE(base::CreateTemporaryFileInDir(new_dir, &temp_file));
  EXPECT_FALSE(platform_.RemoveEmptyDirectory(path));
}

TEST_F(PlatformTest, SetMountUserToRoot) {
  EXPECT_TRUE(platform_.SetMountUser("root"));
  EXPECT_EQ(0, platform_.mount_user_id());
  EXPECT_EQ(0, platform_.mount_group_id());
  EXPECT_EQ("root", platform_.mount_user());
}

TEST_F(PlatformTest, SetMountUserToNonexistentUser) {
  uid_t user_id = platform_.mount_user_id();
  gid_t group_id = platform_.mount_group_id();
  string user = platform_.mount_user();
  EXPECT_FALSE(platform_.SetMountUser("nonexistent-user"));
  EXPECT_EQ(user_id, platform_.mount_user_id());
  EXPECT_EQ(group_id, platform_.mount_group_id());
  EXPECT_EQ(user, platform_.mount_user());
}

TEST_F(PlatformTest, SetOwnershipOfNonExistentPath) {
  EXPECT_FALSE(platform_.SetOwnership("/nonexistent-path", getuid(), getgid()));
}

TEST_F(PlatformTest, SetOwnershipOfExistentPath) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  string path = temp_dir.path().value();

  EXPECT_TRUE(platform_.SetOwnership(path, getuid(), getgid()));
  EXPECT_TRUE(CheckOwnership(path, getuid(), getgid()));
}

TEST_F(PlatformTest, SetPermissionsOfNonExistentPath) {
  EXPECT_FALSE(platform_.SetPermissions("/nonexistent-path", S_IRWXU));
}

TEST_F(PlatformTest, SetPermissionsOfExistentPath) {
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  string path = temp_dir.path().value();

  mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
  EXPECT_TRUE(platform_.SetPermissions(path, mode));
  EXPECT_TRUE(CheckPermissions(path, mode));

  mode = S_IRWXU | S_IRGRP | S_IXGRP;
  EXPECT_TRUE(platform_.SetPermissions(path, mode));
  EXPECT_TRUE(CheckPermissions(path, mode));

  mode = S_IRWXU;
  EXPECT_TRUE(platform_.SetPermissions(path, mode));
  EXPECT_TRUE(CheckPermissions(path, mode));
}

}  // namespace cros_disks
