// 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 "cryptohome/persistent_lookup_table.h"

#include <base/files/file_util.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>

namespace {

// Helper function to create a file path, given a key directory
// |key_dir| and a version number of the file, |version|.
base::FilePath CreateFilePathForKey(const base::FilePath& key_dir,
                                    uint32_t version) {
  return key_dir.Append(std::to_string(version)).AddExtension("value");
}

}  // namespace

namespace cryptohome {

PersistentLookupTable::PersistentLookupTable(Platform* platform,
                                             base::FilePath basedir)
    : platform_(platform), table_dir_(basedir) {
  CHECK(platform_);
}

PLTError PersistentLookupTable::GetValue(const uint64_t key,
                                         std::vector<uint8_t>* value) {
  uint32_t latest_version = FindLatestVersion(key);

  if (latest_version == 0) {
    VLOG(1) << "No entry exists for this key: " << key;
    return PLT_KEY_NOT_FOUND;
  }

  base::FilePath key_dir = table_dir_.Append(std::to_string(key));
  base::FilePath filepath = CreateFilePathForKey(key_dir, latest_version);
  if (!platform_->ReadFile(filepath, value)) {
    LOG(ERROR) << "Trouble reading file: " << filepath.value();
    return PLT_STORAGE_ERROR;
  }

  // If the key directory has been marked as deleted, we should
  // return a |false|.
  if (value->size() == 0) {
    value->clear();
    return PLT_KEY_NOT_FOUND;
  }

  return PLT_SUCCESS;
}

PLTError PersistentLookupTable::StoreValue(
    const uint64_t key, const std::vector<uint8_t>& new_val) {
  uint32_t latest_version = FindLatestVersion(key);
  base::FilePath key_dir = table_dir_.Append(std::to_string(key));

  // Key doesn't exist.
  if (latest_version == 0) {
    if (!platform_->CreateDirectory(key_dir)) {
      PLOG(ERROR) << "Failed to create key dir: " << key_dir.value();
      return PLT_STORAGE_ERROR;
    }
  }

  // Create new file version.
  uint32_t new_version = latest_version + 1;
  CHECK(new_version);
  base::FilePath new_file = CreateFilePathForKey(key_dir, new_version);

  if (!platform_->WriteFileAtomic(new_file, new_val, 0644)) {
    LOG(ERROR) << "Failed to create disk entry for file: " << new_file.value();
    return PLT_STORAGE_ERROR;
  }

  return PLT_SUCCESS;
}

PLTError PersistentLookupTable::RemoveKey(const uint64_t key) {
  uint32_t latest_version = FindLatestVersion(key);

  if (latest_version != 0) {
    // Create new file version.
    uint32_t new_version = latest_version + 1;
    CHECK(new_version);
    base::FilePath key_dir = table_dir_.Append(std::to_string(key));
    base::FilePath new_file = CreateFilePathForKey(key_dir, new_version);

    if (!platform_->TouchFileDurable(new_file)) {
      LOG(ERROR) << "Failed to create disk entry for file: "
                 << new_file.value();
      // If we couldn't write the "bad" file, something is amiss and we
      // should surface an error.
      return PLT_STORAGE_ERROR;
    }
  }

  // Delete the entire directory anyway.
  DeleteOldKeyVersions(key, 0);
  return PLT_SUCCESS;
}

bool PersistentLookupTable::KeyExists(const uint64_t key) {
  return FindLatestVersion(key) != 0;
}

void PersistentLookupTable::GetUsedKeys(std::vector<uint64_t>* key_list) {
  // Go through all key directories, and if there are valid key entries,
  // add it to the list.
  base::FileEnumerator file(table_dir_, false,
                            base::FileEnumerator::DIRECTORIES);
  for (base::FilePath cur_dir = file.Next(); !cur_dir.empty();
       cur_dir = file.Next()) {
    uint64_t key;
    if (!base::StringToUint64(cur_dir.BaseName().value(), &key)) {
      LOG(WARNING) << "Can't parse directory, skipping: " << cur_dir.value();
      continue;
    }
    if (KeyExists(key)) {
      key_list->push_back(key);
    }
  }
}

bool PersistentLookupTable::InitOnBoot() {
  if (!platform_->DirectoryExists(table_dir_)) {
    VLOG(1) << "Lookup table dir not found, have to create it.";
    if (!platform_->CreateDirectory(table_dir_)) {
      PLOG(ERROR) << "Failed to create dir: " << table_dir_.value();
      return false;
    }
  } else {
    // Remove all old key versions of all keys.
    base::FileEnumerator file(table_dir_, false,
                              base::FileEnumerator::DIRECTORIES);
    for (base::FilePath cur_dir = file.Next(); !cur_dir.empty();
         cur_dir = file.Next()) {
      uint64_t key;
      if (!base::StringToUint64(cur_dir.BaseName().value(), &key)) {
        LOG(WARNING) << "Can't parse directory, skipping: " << cur_dir.value();
        continue;
      }
      uint32_t version = FindLatestVersion(key);
      DeleteOldKeyVersions(key, version);
    }
  }
  return true;
}

uint32_t PersistentLookupTable::FindLatestVersion(const uint64_t key) {
  base::FilePath key_dir = table_dir_.Append(std::to_string(key));
  if (!platform_->DirectoryExists(key_dir)) {
    // No directory with this key, so return 0;
    return 0;
  }

  base::FileEnumerator file(key_dir, false, base::FileEnumerator::FILES,
                            "*.value");
  uint32_t latest_version = 0;
  for (base::FilePath cur_file = file.Next(); !cur_file.empty();
       cur_file = file.Next()) {
    uint32_t cur_version;
    // Get the version number.
    if (!base::StringToUint(cur_file.BaseName().RemoveExtension().value(),
                            &cur_version)) {
      // If the file name is corrupt, we should just skip it.
      LOG(ERROR) << "File name is not of correct format." << cur_file.value();
      continue;
    }

    if (cur_version > latest_version) {
      // TODO(pmalani): Make sure the data in this file is verified.
      latest_version = cur_version;
    }
  }

  return latest_version;
}

void PersistentLookupTable::DeleteOldKeyVersions(const uint64_t key,
                                                 uint32_t version_to_save) {
  base::FilePath key_dir = table_dir_.Append(std::to_string(key));
  if (!platform_->DirectoryExists(key_dir)) {
    return;
  }

  // Delete the entire directory.
  if (version_to_save == 0) {
    if (!platform_->DeletePathRecursively(key_dir)) {
      LOG(WARNING) << "Failed to delete dir: " << key_dir.value();
    }
    return;
  }

  base::FileEnumerator file(key_dir, false, base::FileEnumerator::FILES);
  base::FilePath cur_file;
  while (true) {
    cur_file = file.Next();
    if (cur_file.empty()) {
      break;
    }

    // Ignore file for version |version_to_save|.
    if (cur_file.BaseName().RemoveExtension().value() ==
        std::to_string(version_to_save)) {
      continue;
    }

    if (!platform_->DeleteFile(cur_file)) {
      LOG(WARNING) << "Failed to delete file: " << cur_file.value();
    }
  }
}

}  // namespace cryptohome
