// Copyright 2015 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 "settingsd/blob_store.h"

#include <algorithm>

#include <base/logging.h>
#include <base/strings/stringprintf.h>

#include "settingsd/file_utils.h"
#include "settingsd/key.h"

namespace settingsd {

namespace {

// Defines the maximum length of source ids. This requirement stems from the
// constraints on the maximum length of file sytem entries from the underlying
// operating system.
const unsigned int kMaxSourceIdLength = 255u;

// Defines the length of a blob filename. Note that this must be compatible with
// |kFormatBlobFilename|.
const unsigned int kBlobFilenameLength = 10u;

// Defines the file name format for blobs.
const char kFormatBlobFilename[] = "blob_%05u";

// Defines the path format of the directory for blobs belonging to a source.
const char kFormatSourcePath[] = "%s/%s/";

// Defines the maximum supported size of SettingsBlobs in bytes.
const unsigned int kMaxSettingsBlobSizeBytes = 1024u * 1024u;

}  // namespace

BlobStore::Handle::Handle() : blob_id_(0) {}

BlobStore::Handle::Handle(unsigned int blob_id, const std::string& source_id)
    : blob_id_(blob_id), source_id_(source_id) {}

bool BlobStore::Handle::IsValid() const {
  return blob_id_ != 0 && !source_id_.empty();
}

BlobStore::BlobStore(const std::string& storage_path)
    : storage_path_(storage_path) {
  DCHECK_EQ(base::StringPrintf(kFormatBlobFilename, 0).length(),
            kBlobFilenameLength);
}

BlobStore::Handle BlobStore::Store(const std::string& source_id,
                                   BlobRef blob) const {
  DCHECK(!source_id.empty());

  // Check if the directory for |source_id| exists, if it doesn't, create it.
  std::string source_path = GetSourcePath(source_id);
  if (source_path.empty())
    return Handle();

  if (!utils::PathExists(source_path))
    utils::CreateDirectory(source_path);

  // Determine the next unused blob id, construct the blob path and write blob.
  unsigned int blob_id = GetNextUnusedBlobId(source_id);
  std::string blob_path = GetBlobPath(blob_id, source_id);
  if (blob_path.empty())
    return Handle();
  if (utils::WriteFileAtomically(blob_path, blob.data(), blob.size()))
    return Handle(blob_id, source_id);

  // Failed to write the file. Return an invalid Handle.
  return Handle();
}

const std::vector<uint8_t> BlobStore::Load(Handle handle) const {
  std::vector<uint8_t> blob;
  std::string blob_path = GetBlobPath(handle.blob_id_, handle.source_id_);
  if (blob_path.empty())
    return std::vector<uint8_t>();
  utils::ReadFile(blob_path, &blob, kMaxSettingsBlobSizeBytes);
  return blob;
}

std::vector<BlobStore::Handle> BlobStore::List(
    const std::string& source_id) const {
  std::vector<BlobStore::Handle> handles;
  std::string source_path = GetSourcePath(source_id);
  if (source_path.empty())
    return std::vector<BlobStore::Handle>();
  std::vector<std::string> files = utils::ListFiles(source_path);
  for (auto& file : files) {
    Handle handle(FilenameToBlobId(file), source_id);
    if (handle.IsValid())
      handles.push_back(handle);
  }
  return handles;
}

bool BlobStore::Purge(Handle handle) const {
  if (!handle.IsValid())
    return false;
  std::string blob_path = GetBlobPath(handle.blob_id_, handle.source_id_);
  if (blob_path.empty())
    return false;
  return utils::DeleteFile(blob_path);
}

std::string BlobStore::GetBlobPath(unsigned int blob_id,
                                   const std::string& source_id) const {
  std::string source_path = GetSourcePath(source_id);
  if (source_path.empty())
    return std::string();
  std::string filename = base::StringPrintf(kFormatBlobFilename, blob_id);
  if (kBlobFilenameLength != filename.size()) {
    LOG(ERROR) << "Invalid blob id: " << blob_id;
    return std::string();
  }
  return source_path + filename;
}

std::string BlobStore::GetSourcePath(const std::string& source_id) const {
  if (source_id.empty() || source_id.length() > kMaxSourceIdLength ||
      !Key::IsValidKey(source_id)) {
    LOG(ERROR) << "Invalid source id: " << source_id;
    return std::string();
  }
  return base::StringPrintf(kFormatSourcePath, storage_path_.c_str(),
                            source_id.c_str());
}

unsigned int BlobStore::FilenameToBlobId(const std::string& filename) const {
  unsigned int id = 0;
  if (filename.size() != kBlobFilenameLength) {
    LOG(ERROR) << "Not a blob filename: " << filename;
    return id;
  }
  sscanf(filename.c_str(), kFormatBlobFilename, &id);
  return id;
}

unsigned int BlobStore::GetNextUnusedBlobId(
    const std::string& source_id) const {
  std::vector<std::string> files = utils::ListFiles(GetSourcePath(source_id));

  // Sort the filenames lexicographically and reverse iterate over them. Note
  // that due to the filename format <<kPrefix>>_XXXXX filenames lexicographic
  // sorting and blob id sorting are the same.
  std::sort(files.begin(), files.end());
  for (auto it = files.rbegin(); it != files.rend(); ++it) {
    // Attempt to extract the blob id from the filename.
    unsigned int id = FilenameToBlobId(*it);

    // If this file does not follow our naming scheme, go to next file.
    if (!id)
      continue;

    return id + 1;
  }

  // No previous blob for |source_id| found.
  return 1;
}

}  // namespace settingsd
