// 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 <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/test/bind_test_util.h>
#include <gtest/gtest.h>

#include "usb_bouncer/util.h"
#include "usb_bouncer/util_internal.h"

namespace usb_bouncer {

namespace {

constexpr char kSubdirName[] = "subdir";
constexpr char kSysFSAuthorized[] = "authorized";
constexpr char kSysFSAuthorizedDefault[] = "authorized_default";
constexpr char kSysFSEnabled[] = "1";
constexpr char kSysFSDisabled[] = "0";

bool CreateDisabledFlag(const base::FilePath& flag) {
  if (!base::WriteFile(flag, kSysFSDisabled, sizeof(kSysFSDisabled) - 1)) {
    LOG(ERROR) << "WriteFile('" << flag.value() << "', ...) failed.";
    return false;
  }
  return true;
}

bool CreateDeviceNode(const base::FilePath& dir) {
  if (!base::CreateDirectory(dir)) {
    LOG(ERROR) << "CreateDirectory('" << dir.value() << "') failed.";
    return false;
  }

  return CreateDisabledFlag(dir.Append(kSysFSAuthorized)) &&
         CreateDisabledFlag(dir.Append(kSysFSAuthorizedDefault));
}

bool CheckEnabledFlag(const base::FilePath& flag) {
  std::string flag_content;
  if (!base::ReadFileToString(flag, &flag_content)) {
    LOG(ERROR) << "ReadFileToString('" << flag.value() << "', ...) failed.";
    return false;
  }
  return flag_content == kSysFSEnabled;
}

bool CheckDeviceNodeAuthorized(const base::FilePath& dir) {
  return CheckEnabledFlag(dir.Append(kSysFSAuthorized)) &&
         CheckEnabledFlag(dir.Append(kSysFSAuthorizedDefault));
}

// Mock for testing ForkAndWaitIfDoesNotExist(...). It sets the |taken| to true,
// and always returns 0. If |to_create| isn't empty, it creates a directory at
// that path to make it possible to test the case the path is created after the
// fork.
int ForkMock(bool* taken, const base::FilePath& to_create) {
  *taken = true;

  if (!to_create.empty()) {
    base::CreateDirectory(to_create);
  }

  // Always take the child path, because the parent path exits.
  return 0;
}

}  // namespace

TEST(UtilTest, IncludeRuleAtLockscreen) {
  EXPECT_FALSE(IncludeRuleAtLockscreen(""));

  const std::string blocked_device =
      "allow id 0781:5588 serial \"12345678BF05\" name \"USB Extreme Pro\" "
      "hash \"9hMkYEMPjuNegGmzLIKwUp2MPctSL0tCWk7ruWGuOzc=\" with-interface "
      "08:06:50 with-connect-type \"unknown\"";
  EXPECT_FALSE(IncludeRuleAtLockscreen(blocked_device))
      << "Failed to filter: " << blocked_device;

  const std::string allowed_device =
      "allow id 0bda:8153 serial \"000001000000\" name \"USB 10/100/1000 LAN\" "
      "hash \"dljXy8thtljhoJo+O+hfhSlp1J89rz0Z4404iqKzakI=\" with-interface "
      "{ ff:ff:00 02:06:00 0a:00:00 0a:00:00 }";
  EXPECT_TRUE(IncludeRuleAtLockscreen(allowed_device))
      << "Failed to allow:" << allowed_device;
}

TEST(UtilTest, AuthorizeAll_Success) {
  base::ScopedTempDir temp_dir_;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()) << strerror(errno);
  ASSERT_TRUE(AuthorizeAll(temp_dir_.GetPath().value()));

  const base::FilePath subdir = temp_dir_.GetPath().Append(kSubdirName);
  ASSERT_TRUE(CreateDeviceNode(subdir))
      << "CreateDeviceNode('" << subdir.value() << "') failed.";
  const base::FilePath deepdir =
      temp_dir_.GetPath().Append(kSubdirName).Append(kSubdirName);
  ASSERT_TRUE(CreateDeviceNode(deepdir))
      << "CreateDeviceNode('" << deepdir.value() << "') failed.";

  EXPECT_TRUE(AuthorizeAll(temp_dir_.GetPath().value()));
  EXPECT_TRUE(CheckDeviceNodeAuthorized(subdir));
  EXPECT_TRUE(CheckDeviceNodeAuthorized(deepdir));
}

TEST(UtilTest, AuthorizeAll_Failure) {
  base::ScopedTempDir temp_dir_;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()) << strerror(errno);

  const base::FilePath subdir = temp_dir_.GetPath().Append(kSubdirName);
  ASSERT_TRUE(CreateDeviceNode(subdir))
      << "CreateDeviceNode('" << subdir.value() << "') failed.";
  const base::FilePath deepdir =
      temp_dir_.GetPath().Append(kSubdirName).Append(kSubdirName);
  ASSERT_TRUE(CreateDeviceNode(deepdir))
      << "CreateDeviceNode('" << deepdir.value() << "') failed.";

  chmod(subdir.Append(kSysFSAuthorizedDefault).value().c_str(), 0000);

  EXPECT_FALSE(AuthorizeAll(temp_dir_.GetPath().value()));
  EXPECT_FALSE(CheckDeviceNodeAuthorized(subdir));
  EXPECT_TRUE(CheckDeviceNodeAuthorized(deepdir));
}

TEST(UtilTest, ForkAndWaitIfNotReady_Ready) {
  base::FilePath empty_path;
  base::ScopedTempDir temp_dir_;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()) << strerror(errno);
  const base::FilePath temp_dir_path = temp_dir_.GetPath();

  bool fork_taken = false;
  EXPECT_TRUE(ForkAndWaitIfNotReady(
      base::BindLambdaForTesting(
          [&temp_dir_path]() -> bool { return PathExists(temp_dir_path); }),
      "temp_dir doesn't exist", base::TimeDelta::FromSeconds(0),
      base::Bind(&ForkMock, base::Unretained(&fork_taken), empty_path)));
  EXPECT_FALSE(fork_taken);
}

TEST(UtilTest, ForkAndWaitIfPathUnavailable_PathDoesntExistTimeout) {
  base::FilePath empty_path;
  base::ScopedTempDir temp_dir_;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()) << strerror(errno);
  base::FilePath sub_dir_ = temp_dir_.GetPath().Append("DoesNotExist");
  LOG(INFO) << "PATH: " << sub_dir_.value();

  bool fork_taken = false;
  EXPECT_FALSE(ForkAndWaitIfNotReady(
      base::BindLambdaForTesting(
          [&sub_dir_]() -> bool { return PathExists(sub_dir_); }),
      "sub_dir_ doesn't exist", base::TimeDelta::FromSeconds(0),
      base::Bind(&ForkMock, base::Unretained(&fork_taken), empty_path)));
  EXPECT_TRUE(fork_taken);
}

TEST(UtilTest, ForkAndWaitIfPathUnavailable_PathDoesntExistSucceed) {
  base::ScopedTempDir temp_dir_;
  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()) << strerror(errno);
  base::FilePath sub_dir_ = temp_dir_.GetPath().Append("ExistsAfterFork");

  bool fork_taken = false;
  EXPECT_TRUE(ForkAndWaitIfNotReady(
      base::BindLambdaForTesting(
          [&sub_dir_]() -> bool { return PathExists(sub_dir_); }),
      "sub_dir_ doesn't exist", base::TimeDelta::FromSeconds(1),
      base::Bind(&ForkMock, base::Unretained(&fork_taken), sub_dir_)));
  EXPECT_TRUE(fork_taken);
}

TEST(UtilTest, GetRuleFromString_Success) {
  EXPECT_TRUE(GetRuleFromString("allow id 0000:0000"));
}

TEST(UtilTest, GetRuleFromString_Failure) {
  EXPECT_FALSE(GetRuleFromString("aaff44"));
}

TEST(UtilTest, GetClassFromRule_EmptyInterfaces) {
  auto rule = GetRuleFromString("allow id 0000:0000");
  ASSERT_TRUE(rule);
  ASSERT_TRUE(rule.attributeWithInterface().empty());
  EXPECT_EQ(GetClassFromRule(rule), UMADeviceClass::kOther);
}

TEST(UtilTest, GetClassFromRule_SingleInterface) {
  auto rule = GetRuleFromString("allow with-interface 03:00:01");
  ASSERT_TRUE(rule);
  ASSERT_EQ(rule.attributeWithInterface().count(), 1);
  EXPECT_EQ(GetClassFromRule(rule), UMADeviceClass::kHID);
}

TEST(UtilTest, GetClassFromRule_MatchingInterfaces) {
  auto rule = GetRuleFromString("allow with-interface { 03:00:00 03:00:01 }");
  ASSERT_TRUE(rule);
  ASSERT_EQ(rule.attributeWithInterface().count(), 2);
  EXPECT_EQ(GetClassFromRule(rule), UMADeviceClass::kHID);
}

TEST(UtilTest, GetClassFromRule_DifferentInterfaces) {
  auto rule = GetRuleFromString("allow with-interface { 03:00:00 09:00:00 }");
  ASSERT_TRUE(rule);
  ASSERT_EQ(rule.attributeWithInterface().count(), 2);
  EXPECT_EQ(GetClassFromRule(rule), UMADeviceClass::kOther);
}

TEST(UtilTest, GetClassFromRule_AV) {
  auto rule =
      GetRuleFromString("allow with-interface { 01:00:00 0E:00:00 10:00:00 }");
  ASSERT_TRUE(rule);
  ASSERT_EQ(rule.attributeWithInterface().count(), 3);
  EXPECT_EQ(GetClassFromRule(rule), UMADeviceClass::kAV);
}

}  // namespace usb_bouncer
