/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "storage/storage_module.h"

#include <chrono>
#include <ctime>
#include <iomanip>
#include <memory>
#include <utility>

#include "common/bind.h"
#include "os/alarm.h"
#include "os/files.h"
#include "os/handler.h"
#include "os/parameter_provider.h"
#include "os/system_properties.h"
#include "storage/config_cache.h"
#include "storage/legacy_config_file.h"
#include "storage/mutation.h"

namespace bluetooth {
namespace storage {

using common::ListMap;
using common::LruCache;
using os::Alarm;
using os::Handler;

static const std::string kFactoryResetProperty = "persist.bluetooth.factoryreset";

static const size_t kDefaultTempDeviceCapacity = 10000;
// Save config whenever there is a change, but delay it by this value so that burst config change won't overwhelm disk
static const std::chrono::milliseconds kDefaultConfigSaveDelay = std::chrono::milliseconds(3000);
// Writing a config to disk takes a minimum 10 ms on a decent x86_64 machine, and 20 ms if including backup file
// The config saving delay must be bigger than this value to avoid overwhelming the disk
static const std::chrono::milliseconds kMinConfigSaveDelay = std::chrono::milliseconds(20);

const int kConfigFileComparePass = 1;
const int kConfigBackupComparePass = 2;
const std::string kConfigFilePrefix = "bt_config-origin";
const std::string kConfigFileHash = "hash";

const std::string StorageModule::kInfoSection = "Info";
const std::string StorageModule::kFileSourceProperty = "FileSource";
const std::string StorageModule::kTimeCreatedProperty = "TimeCreated";
const std::string StorageModule::kTimeCreatedFormat = "%Y-%m-%d %H:%M:%S";

const std::string StorageModule::kAdapterSection = "Adapter";

StorageModule::StorageModule(
    std::string config_file_path,
    std::chrono::milliseconds config_save_delay,
    size_t temp_devices_capacity,
    bool is_restricted_mode,
    bool is_single_user_mode)
    : config_file_path_(std::move(config_file_path)),
      config_save_delay_(config_save_delay),
      temp_devices_capacity_(temp_devices_capacity),
      is_restricted_mode_(is_restricted_mode),
      is_single_user_mode_(is_single_user_mode) {
  // e.g. "/data/misc/bluedroid/bt_config.conf" to "/data/misc/bluedroid/bt_config.bak"
  config_backup_path_ = config_file_path_.substr(0, config_file_path_.find_last_of('.')) + ".bak";
  ASSERT_LOG(
      config_save_delay > kMinConfigSaveDelay,
      "Config save delay of %lld ms is not enough, must be at least %lld ms to avoid overwhelming the disk",
      config_save_delay_.count(),
      kMinConfigSaveDelay.count());
};

StorageModule::~StorageModule() {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  pimpl_.reset();
}

const ModuleFactory StorageModule::Factory = ModuleFactory([]() {
  return new StorageModule(
      os::ParameterProvider::ConfigFilePath(), kDefaultConfigSaveDelay, kDefaultTempDeviceCapacity, false, false);
});

struct StorageModule::impl {
  explicit impl(Handler* handler, ConfigCache cache, size_t in_memory_cache_size_limit)
      : config_save_alarm_(handler), cache_(std::move(cache)), memory_only_cache_(in_memory_cache_size_limit, {}) {}
  Alarm config_save_alarm_;
  ConfigCache cache_;
  ConfigCache memory_only_cache_;
  bool has_pending_config_save_ = false;
};

Mutation StorageModule::Modify() {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  return Mutation(&pimpl_->cache_, &pimpl_->memory_only_cache_);
}

ConfigCache* StorageModule::GetConfigCache() {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  return &pimpl_->cache_;
}

ConfigCache* StorageModule::GetMemoryOnlyConfigCache() {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  return &pimpl_->memory_only_cache_;
}

void StorageModule::SaveDelayed() {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  if (pimpl_->has_pending_config_save_) {
    return;
  }
  pimpl_->config_save_alarm_.Schedule(
      common::BindOnce(&StorageModule::SaveImmediately, common::Unretained(this)), config_save_delay_);
  pimpl_->has_pending_config_save_ = true;
}

void StorageModule::SaveImmediately() {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  if (pimpl_->has_pending_config_save_) {
    pimpl_->config_save_alarm_.Cancel();
    pimpl_->has_pending_config_save_ = false;
  }
  // 1. rename old config to backup name
  if (os::FileExists(config_file_path_)) {
    ASSERT(os::RenameFile(config_file_path_, config_backup_path_));
  }
  // 2. write in-memory config to disk, if failed, backup can still be used
  ASSERT(LegacyConfigFile::FromPath(config_file_path_).Write(pimpl_->cache_));
  // 3. now write back up to disk as well
  ASSERT(LegacyConfigFile::FromPath(config_backup_path_).Write(pimpl_->cache_));
  // 4. save checksum if it is running in common criteria mode
  if (bluetooth::os::ParameterProvider::GetBtKeystoreInterface() != nullptr &&
      bluetooth::os::ParameterProvider::IsCommonCriteriaMode()) {
    bluetooth::os::ParameterProvider::GetBtKeystoreInterface()->set_encrypt_key_or_remove_key(
        kConfigFilePrefix, kConfigFileHash);
  }
}

void StorageModule::ListDependencies(ModuleList* list) const {
  // No dependencies
}

void StorageModule::Start() {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  std::string file_source;
  if (os::GetSystemProperty(kFactoryResetProperty) == "true") {
    LegacyConfigFile::FromPath(config_file_path_).Delete();
    LegacyConfigFile::FromPath(config_backup_path_).Delete();
  }
  if (!is_config_checksum_pass(kConfigFileComparePass)) {
    LegacyConfigFile::FromPath(config_file_path_).Delete();
  }
  if (!is_config_checksum_pass(kConfigBackupComparePass)) {
    LegacyConfigFile::FromPath(config_backup_path_).Delete();
  }
  auto config = LegacyConfigFile::FromPath(config_file_path_).Read(temp_devices_capacity_);
  if (!config || !config->HasSection(kAdapterSection)) {
    LOG_WARN("cannot load config at %s, using backup at %s.", config_file_path_.c_str(), config_backup_path_.c_str());
    config = LegacyConfigFile::FromPath(config_backup_path_).Read(temp_devices_capacity_);
    file_source = "Backup";
  }
  if (!config || !config->HasSection(kAdapterSection)) {
    LOG_WARN("cannot load backup config at %s; creating new empty ones", config_backup_path_.c_str());
    config.emplace(temp_devices_capacity_, Device::kLinkKeyProperties);
    file_source = "Empty";
  }
  if (!file_source.empty()) {
    config->SetProperty(kInfoSection, kFileSourceProperty, std::move(file_source));
  }
  // Cleanup temporary pairings if we have left guest mode
  if (!is_restricted_mode_) {
    config->RemoveSectionWithProperty("Restricted");
  }
  // Read or set config file creation timestamp
  auto time_str = config->GetProperty(kInfoSection, kTimeCreatedProperty);
  if (!time_str) {
    std::stringstream ss;
    auto now = std::chrono::system_clock::now();
    auto now_time_t = std::chrono::system_clock::to_time_t(now);
    ss << std::put_time(std::localtime(&now_time_t), kTimeCreatedFormat.c_str());
    config->SetProperty(kInfoSection, kTimeCreatedProperty, ss.str());
  }
  config->FixDeviceTypeInconsistencies();
  config->SetPersistentConfigChangedCallback([this] { this->CallOn(this, &StorageModule::SaveDelayed); });
  // TODO (b/158035889) Migrate metrics module to GD
  pimpl_ = std::make_unique<impl>(GetHandler(), std::move(config.value()), temp_devices_capacity_);
  SaveDelayed();
  if (bluetooth::os::ParameterProvider::GetBtKeystoreInterface() != nullptr) {
    bluetooth::os::ParameterProvider::GetBtKeystoreInterface()->ConvertEncryptOrDecryptKeyIfNeeded();
  }
}

void StorageModule::Stop() {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  SaveImmediately();
  if (bluetooth::os::ParameterProvider::GetBtKeystoreInterface() != nullptr) {
    bluetooth::os::ParameterProvider::GetBtKeystoreInterface()->clear_map();
  }
  pimpl_.reset();
}

std::string StorageModule::ToString() const {
  return "Storage Module";
}

Device StorageModule::GetDeviceByLegacyKey(hci::Address legacy_key_address) {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  return Device(
      &pimpl_->cache_,
      &pimpl_->memory_only_cache_,
      std::move(legacy_key_address),
      Device::ConfigKeyAddressType::LEGACY_KEY_ADDRESS);
}

Device StorageModule::GetDeviceByClassicMacAddress(hci::Address classic_address) {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  return Device(
      &pimpl_->cache_,
      &pimpl_->memory_only_cache_,
      std::move(classic_address),
      Device::ConfigKeyAddressType::CLASSIC_ADDRESS);
}

Device StorageModule::GetDeviceByLeIdentityAddress(hci::Address le_identity_address) {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  return Device(
      &pimpl_->cache_,
      &pimpl_->memory_only_cache_,
      std::move(le_identity_address),
      Device::ConfigKeyAddressType::LE_IDENTITY_ADDRESS);
}

AdapterConfig StorageModule::GetAdapterConfig() {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  return AdapterConfig(&pimpl_->cache_, &pimpl_->memory_only_cache_, kAdapterSection);
}

std::vector<Device> StorageModule::GetBondedDevices() {
  std::lock_guard<std::recursive_mutex> lock(mutex_);
  auto persistent_sections = GetConfigCache()->GetPersistentSections();
  std::vector<Device> result;
  result.reserve(persistent_sections.size());
  for (const auto& section : persistent_sections) {
    result.emplace_back(&pimpl_->cache_, &pimpl_->memory_only_cache_, section);
  }
  return result;
}

bool StorageModule::is_config_checksum_pass(int check_bit) {
  return ((os::ParameterProvider::GetCommonCriteriaConfigCompareResult() & check_bit) == check_bit);
}

}  // namespace storage
}  // namespace bluetooth
