// Copyright 2020 The Chromium 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 "chrome/browser/component_updater/zxcvbn_data_component_installer.h"

#include <stdint.h>

#include <array>
#include <memory>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/containers/flat_map.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/util/ranges/algorithm.h"
#include "base/values.h"
#include "base/version.h"
#include "components/component_updater/component_installer.h"
#include "components/component_updater/component_updater_service.h"
#include "components/update_client/update_client.h"
#include "components/update_client/update_client_errors.h"
#include "components/update_client/utils.h"
#include "third_party/zxcvbn-cpp/native-src/zxcvbn/frequency_lists.hpp"

namespace component_updater {

constexpr base::FilePath::StringPieceType
    ZxcvbnDataComponentInstallerPolicy::kEnglishWikipediaTxtFileName;
constexpr base::FilePath::StringPieceType
    ZxcvbnDataComponentInstallerPolicy::kFemaleNamesTxtFileName;
constexpr base::FilePath::StringPieceType
    ZxcvbnDataComponentInstallerPolicy::kMaleNamesTxtFileName;
constexpr base::FilePath::StringPieceType
    ZxcvbnDataComponentInstallerPolicy::kPasswordsTxtFileName;
constexpr base::FilePath::StringPieceType
    ZxcvbnDataComponentInstallerPolicy::kSurnamesTxtFileName;
constexpr base::FilePath::StringPieceType
    ZxcvbnDataComponentInstallerPolicy::kUsTvAndFilmTxtFileName;

namespace {

// Small struct linking a dictionary tag with the corresponding filename.
struct TagAndFileName {
  zxcvbn::DictionaryTag tag;
  base::FilePath::StringPieceType file_name;
};

constexpr std::array<TagAndFileName, 6> kTagAndFileNamePairs = {{
    {zxcvbn::DictionaryTag::ENGLISH_WIKIPEDIA,
     ZxcvbnDataComponentInstallerPolicy::kEnglishWikipediaTxtFileName},
    {zxcvbn::DictionaryTag::FEMALE_NAMES,
     ZxcvbnDataComponentInstallerPolicy::kFemaleNamesTxtFileName},
    {zxcvbn::DictionaryTag::MALE_NAMES,
     ZxcvbnDataComponentInstallerPolicy::kMaleNamesTxtFileName},
    {zxcvbn::DictionaryTag::PASSWORDS,
     ZxcvbnDataComponentInstallerPolicy::kPasswordsTxtFileName},
    {zxcvbn::DictionaryTag::SURNAMES,
     ZxcvbnDataComponentInstallerPolicy::kSurnamesTxtFileName},
    {zxcvbn::DictionaryTag::US_TV_AND_FILM,
     ZxcvbnDataComponentInstallerPolicy::kUsTvAndFilmTxtFileName},
}};

using DictionaryMap = base::flat_map<zxcvbn::DictionaryTag, std::string>;
DictionaryMap ReadDictionaries(const base::FilePath& install_dir) {
  DictionaryMap result;
  result.reserve(kTagAndFileNamePairs.size());
  for (const auto& pair : kTagAndFileNamePairs) {
    base::FilePath dictionary_path = install_dir.Append(pair.file_name);
    DVLOG(1) << "Reading Dictionary from file: " << dictionary_path;

    std::string dictionary;
    if (base::ReadFileToString(dictionary_path, &dictionary))
      result.try_emplace(result.end(), pair.tag, std::move(dictionary));
    else
      VLOG(1) << "Failed reading from " << dictionary_path;
  }

  return result;
}

void ParseDictionaries(const DictionaryMap& dictionaries) {
  for (const auto& pair : dictionaries) {
    if (!zxcvbn::ParseRankedDictionary(pair.first, pair.second)) {
      VLOG(1) << "Failed to parse dictionary for tag "
              << static_cast<int>(pair.first) << ". Contents: " << pair.second;
    }
  }
}

// The SHA256 of the SubjectPublicKeyInfo used to sign the extension.
// The extension id is: ojhpjlocmbogdgmfpkhlaaeamibhnphh
constexpr std::array<uint8_t, 32> kZxcvbnDataPublicKeySha256 = {
    0xe9, 0x7f, 0x9b, 0xe2, 0xc1, 0xe6, 0x36, 0xc5, 0xfa, 0x7b, 0x00,
    0x40, 0xc8, 0x17, 0xdf, 0x77, 0x34, 0x64, 0x84, 0x70, 0x3d, 0xa2,
    0x14, 0x9a, 0x79, 0x99, 0x57, 0xa7, 0x1e, 0x66, 0xf5, 0xb3,
};

}  // namespace

bool ZxcvbnDataComponentInstallerPolicy::VerifyInstallation(
    const base::DictionaryValue& manifest,
    const base::FilePath& install_dir) const {
  return util::ranges::all_of(kTagAndFileNamePairs, [&](const auto& pair) {
    return base::PathExists(install_dir.Append(pair.file_name));
  });
}

bool ZxcvbnDataComponentInstallerPolicy::
    SupportsGroupPolicyEnabledComponentUpdates() const {
  return false;
}

bool ZxcvbnDataComponentInstallerPolicy::RequiresNetworkEncryption() const {
  return false;
}

update_client::CrxInstaller::Result
ZxcvbnDataComponentInstallerPolicy::OnCustomInstall(
    const base::DictionaryValue& manifest,
    const base::FilePath& install_dir) {
  return update_client::CrxInstaller::Result(update_client::InstallError::NONE);
}

void ZxcvbnDataComponentInstallerPolicy::OnCustomUninstall() {}

void ZxcvbnDataComponentInstallerPolicy::ComponentReady(
    const base::Version& version,
    const base::FilePath& install_dir,
    std::unique_ptr<base::DictionaryValue> manifest) {
  DVLOG(1) << "Zxcvbn Data Component ready, version " << version.GetString()
           << " in " << install_dir;

  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
      base::BindOnce(&ReadDictionaries, install_dir),
      base::BindOnce(&ParseDictionaries));
}

base::FilePath ZxcvbnDataComponentInstallerPolicy::GetRelativeInstallDir()
    const {
  return base::FilePath(FILE_PATH_LITERAL("ZxcvbnData"));
}

void ZxcvbnDataComponentInstallerPolicy::GetHash(
    std::vector<uint8_t>* hash) const {
  hash->assign(kZxcvbnDataPublicKeySha256.begin(),
               kZxcvbnDataPublicKeySha256.end());
}

std::string ZxcvbnDataComponentInstallerPolicy::GetName() const {
  return "Zxcvbn Data Dictionaries";
}

std::vector<std::string> ZxcvbnDataComponentInstallerPolicy::GetMimeTypes()
    const {
  return std::vector<std::string>();
}

update_client::InstallerAttributes
ZxcvbnDataComponentInstallerPolicy::GetInstallerAttributes() const {
  return update_client::InstallerAttributes();
}

void RegisterZxcvbnDataComponent(ComponentUpdateService* cus) {
  base::MakeRefCounted<ComponentInstaller>(
      std::make_unique<ZxcvbnDataComponentInstallerPolicy>())
      ->Register(cus, base::NullCallback());
}

}  // namespace component_updater
