// Copyright 2018 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 "usb_bouncer/entry_manager_test_util.h"

#include <base/files/file_util.h>
#include <base/logging.h>

#include "usb_bouncer/util.h"

namespace usb_bouncer {

namespace {

constexpr char kUsbguardTestConfigFilename[] = "99-rules.conf";
constexpr char kUsbguardTestConfigFooter[] = "block\n";

bool EntryMapContains(const EntryMap& entries,
                      const std::string& key,
                      const std::string& value) {
  auto entry = entries.find(key);

  if (entry == entries.end()) {
    return false;
  }

  if (entry->second.rules().size() != 1) {
    return false;
  }

  return value == entry->second.rules(0);
}

bool ExpireEntryHelper(EntryMap* entries, const std::string& key) {
  auto entry = entries->find(key);

  if (entry == entries->end()) {
    return false;
  }

  if (entry->second.rules().size() != 1) {
    return false;
  }

  entry->second.mutable_last_used()->clear_seconds();
  return true;
}

}  // namespace

EntryManagerTestUtil::EntryManagerTestUtil() {
  CHECK(scoped_temp_dir_.CreateUniqueTempDir());
  temp_dir_ = scoped_temp_dir_.GetPath();
  CHECK(base::SetPosixFilePermissions(temp_dir_, 0755));

  base::FilePath temp_etc_usbguard =
      CreateTestDir(kUsbguardPolicyDir, true /*force_empty*/);
  CHECK_NE(base::WriteFile(
               temp_etc_usbguard.Append(kUsbguardTestConfigFilename),
               kUsbguardTestConfigFooter, sizeof(kUsbguardTestConfigFooter)),
           -1);

  CreateTestDir(std::string("sys") + kDefaultDevpath, true /*force_empty*/);
  CreateTestDir(kUserDbBaseDir, true /*force_empty*/);

  RecreateEntryManager(base::FilePath() /*userdb_dir*/);
}

EntryManager* EntryManagerTestUtil::Get() {
  return entry_manager_.get();
}

void EntryManagerTestUtil::RefreshDB(bool include_user_db, bool new_db) {
  if (new_db && entry_manager_) {
    if (!base::DeletePathRecursively(entry_manager_->global_db_.path())) {
      LOG(FATAL) << "Unable to delete \""
                 << entry_manager_->global_db_.path().value() << "\"!";
    }
  }
  if (include_user_db) {
    base::FilePath user_db_dir = CreateTestDir(kUserdbDir, new_db);
    CHECK(!user_db_dir.empty());
    RecreateEntryManager(user_db_dir);
  } else {
    RecreateEntryManager(base::FilePath());
  }
}

void EntryManagerTestUtil::ReplaceDB(const RuleDB& replacement) {
  entry_manager_->global_db_.Get() = replacement;
}

void EntryManagerTestUtil::SetUserDBReadOnly(bool user_db_read_only) {
  entry_manager_->user_db_read_only_ = user_db_read_only;
}

void EntryManagerTestUtil::SetIsGuestSession(bool is_guest_session) {
  entry_manager_->is_guest_session_ = is_guest_session;
}

void EntryManagerTestUtil::ExpireEntry(bool expect_user,
                                       const std::string& devpath,
                                       const std::string& rule) {
  CHECK(ExpireEntryHelper(entry_manager_->global_db_.Get().mutable_trash(),
                          Hash(devpath)));

  if (expect_user) {
    CHECK(entry_manager_->user_db_.Valid());
    CHECK(ExpireEntryHelper(entry_manager_->user_db_.Get().mutable_entries(),
                            Hash(rule)));
  }
}

size_t EntryManagerTestUtil::GarbageCollectInternal(bool global_only) {
  return entry_manager_->GarbageCollectInternal(global_only);
}

bool EntryManagerTestUtil::GlobalDBContainsEntry(const std::string& devpath,
                                                 const std::string& rule) {
  return EntryMapContains(entry_manager_->global_db_.Get().entries(),
                          Hash(devpath), rule);
}

bool EntryManagerTestUtil::GlobalTrashContainsEntry(const std::string& devpath,
                                                    const std::string& rule) {
  return EntryMapContains(entry_manager_->global_db_.Get().trash(),
                          Hash(devpath), rule);
}

bool EntryManagerTestUtil::UserDBContainsEntry(const std::string& rule) {
  CHECK(entry_manager_->user_db_.Valid());
  return EntryMapContains(entry_manager_->user_db_.Get().entries(), Hash(rule),
                          rule);
}

base::FilePath EntryManagerTestUtil::CreateTestDir(const std::string& dir,
                                                   bool force_empty) {
  base::FilePath result;
  if (!dir.empty() && dir.front() == '/') {
    result = temp_dir_.Append(dir.substr(1));
  } else {
    result = temp_dir_.Append(dir);
  }
  if (force_empty) {
    if (!base::DeletePathRecursively(result)) {
      LOG(FATAL) << "Unable to clear directory \"" << result.value() << "\"!";
    }
  }
  base::File::Error error;
  if (!base::CreateDirectoryAndGetError(result, &error)) {
    LOG(FATAL) << "Unable to create temp directory \"" << result.value()
               << "\"!";
  }
  return result;
}

void EntryManagerTestUtil::RecreateEntryManager(
    const base::FilePath& userdb_dir) {
  // Make sure old entry_manager_ is cleaned up before creating another to
  // release the file lock.
  entry_manager_.reset();
  // std::make_unique was not used because a private constructor was needed.
  entry_manager_.reset(
      new EntryManager(temp_dir_.value(), userdb_dir,
                       false /*user_db_read_only*/, false /*is_guest_session*/,
                       [](const std::string& devpath) -> std::string {
                         if (devpath.empty()) {
                           return "";
                         }
                         return kDefaultRule;
                       }));
  CHECK(entry_manager_->global_db_.Valid());
}

}  // namespace usb_bouncer
