// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/component_updater/metadata_table_chromeos.h"

#include <algorithm>
#include <memory>
#include <string_view>
#include <utility>
#include <vector>

#include "base/hash/sha1.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "components/component_updater/component_updater_paths.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_thread.h"

namespace component_updater {

namespace {

// Path to the DictionaryValue in PrefService.
constexpr char kMetadataPrefPath[] = "component_updater_metadata";

// Schema of the DictionaryValue:
// {
//   |kMetadataContentKey|:
//   {
//     {
//       |kMetadataContentItemHashedUserIdKey|: |hashed_user_id|,
//       |kMetadataContentItemComponentKey|: |component|,
//     },
//     ...
//   }
// }
//
// Key to the content (installed items) in the DictionaryValue.
constexpr char kMetadataContentKey[] = "installed_items";

// Key to the hashed user id that installs the component.
constexpr char kMetadataContentItemHashedUserIdKey[] = "hashed_user_id";
// Key to the component name.
constexpr char kMetadataContentItemComponentKey[] = "component";

// Gets current active user.
const user_manager::User* GetActiveUser() {
  DCHECK(user_manager::UserManager::Get());

  return user_manager::UserManager::Get()->GetActiveUser();
}

// Converts username to a hashed string.
//
// The result is converted to lowercase to stay compatible with
// CryptoLib::HexEncodeToBuffer().
std::string HashUsername(std::string_view username) {
  return base::ToLowerASCII(base::HexEncode(
      base::SHA1Hash(base::as_byte_span(base::ToLowerASCII(username)))));
}

const std::string& GetRequiredStringFromDict(const base::Value& dict,
                                             std::string_view key) {
  const std::string* str = dict.GetDict().FindString(key);
  DCHECK(str);
  return *str;
}

}  // namespace

MetadataTable::MetadataTable(PrefService* pref_service)
    : pref_service_(pref_service) {
  DCHECK(pref_service_);
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  Load();
}

MetadataTable::~MetadataTable() = default;

// static
std::unique_ptr<component_updater::MetadataTable>
MetadataTable::CreateForTest() {
  return base::WrapUnique(new MetadataTable());
}

// static
void MetadataTable::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterDictionaryPref(kMetadataPrefPath);
}

bool MetadataTable::AddComponentForCurrentUser(
    const std::string& component_name) {
  const user_manager::User* active_user = GetActiveUser();
  // Return immediately if action is performed when no user is signed in.
  if (!active_user) {
    return false;
  }

  const std::string hashed_user_id =
      HashUsername(active_user->GetAccountId().GetUserEmail());
  AddItem(hashed_user_id, component_name);
  Store();
  return true;
}

bool MetadataTable::DeleteComponentForCurrentUser(
    const std::string& component_name) {
  const user_manager::User* active_user = GetActiveUser();
  // Return immediately if action is performed when no user is signed in.
  if (!active_user) {
    return false;
  }

  const std::string hashed_user_id =
      HashUsername(active_user->GetAccountId().GetUserEmail());
  if (!DeleteItem(hashed_user_id, component_name)) {
    return false;
  }
  Store();
  return true;
}

bool MetadataTable::HasComponentForAnyUser(
    const std::string& component_name) const {
  return std::ranges::any_of(
      installed_items_, [&component_name](const base::Value& item) {
        const std::string& name =
            GetRequiredStringFromDict(item, kMetadataContentItemComponentKey);
        return name == component_name;
      });
}

MetadataTable::MetadataTable() : pref_service_(nullptr) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}

void MetadataTable::Load() {
  DCHECK(pref_service_);
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  const base::Value::Dict& dict = pref_service_->GetDict(kMetadataPrefPath);
  const base::Value::List* installed_items = dict.FindList(kMetadataContentKey);
  if (installed_items) {
    installed_items_ = installed_items->Clone();
    return;
  }
  installed_items_.clear();
  Store();
}

void MetadataTable::Store() {
  DCHECK(pref_service_);
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  ScopedDictPrefUpdate update(pref_service_, kMetadataPrefPath);
  update->Set(kMetadataContentKey, installed_items_.Clone());
}

void MetadataTable::AddItem(const std::string& hashed_user_id,
                            const std::string& component_name) {
  if (HasComponentForUser(hashed_user_id, component_name)) {
    return;
  }

  base::Value::Dict item;
  item.Set(kMetadataContentItemHashedUserIdKey, hashed_user_id);
  item.Set(kMetadataContentItemComponentKey, component_name);
  installed_items_.Append(std::move(item));
}

bool MetadataTable::DeleteItem(const std::string& hashed_user_id,
                               const std::string& component_name) {
  size_t index = GetInstalledItemIndex(hashed_user_id, component_name);
  if (index == installed_items_.size()) {
    return false;
  }
  installed_items_.erase(installed_items_.begin() + index);
  return true;
}

bool MetadataTable::HasComponentForUser(
    const std::string& hashed_user_id,
    const std::string& component_name) const {
  return GetInstalledItemIndex(hashed_user_id, component_name) !=
         installed_items_.size();
}

size_t MetadataTable::GetInstalledItemIndex(
    const std::string& hashed_user_id,
    const std::string& component_name) const {
  for (size_t i = 0; i < installed_items_.size(); ++i) {
    const auto& dict = installed_items_[i];
    const std::string& user_id =
        GetRequiredStringFromDict(dict, kMetadataContentItemHashedUserIdKey);
    if (user_id != hashed_user_id) {
      continue;
    }
    const std::string& name =
        GetRequiredStringFromDict(dict, kMetadataContentItemComponentKey);
    if (name != component_name) {
      continue;
    }
    return i;
  }
  return installed_items_.size();
}

}  // namespace component_updater
