// 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::DeleteFile(entry_manager_->global_db_.path(), true)) {
      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::DeleteFile(result, true)) {
      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
