// Copyright (c) 2010 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 "brillo/key_value_store.h"

#include <string>
#include <vector>

#include <base/files/file_util.h>
#include <base/files/important_file_writer.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <brillo/strings/string_utils.h>
#include <brillo/map_utils.h>

using std::string;
using std::vector;

namespace brillo {

namespace {

// Values used for booleans.
const char kTrueValue[] = "true";
const char kFalseValue[] = "false";

// Returns a copy of |key| with leading and trailing whitespace removed.
string TrimKey(const string& key) {
  string trimmed_key;
  base::TrimWhitespaceASCII(key, base::TRIM_ALL, &trimmed_key);
  CHECK(!trimmed_key.empty());
  return trimmed_key;
}

}  // namespace

KeyValueStore::KeyValueStore() = default;
KeyValueStore::~KeyValueStore() = default;
KeyValueStore::KeyValueStore(KeyValueStore&&) = default;
KeyValueStore& KeyValueStore::operator=(KeyValueStore&&) = default;

bool KeyValueStore::Load(const base::FilePath& path) {
  string file_data;
  if (!base::ReadFileToString(path, &file_data))
    return false;
  return LoadFromString(file_data);
}

bool KeyValueStore::LoadFromString(const std::string& data) {
  // Split along '\n', then along '='.
  vector<string> lines = base::SplitString(data, "\n", base::KEEP_WHITESPACE,
                                           base::SPLIT_WANT_ALL);
  for (auto it = lines.begin(); it != lines.end(); ++it) {
    std::string line;
    base::TrimWhitespaceASCII(*it, base::TRIM_LEADING, &line);
    if (line.empty() || line.front() == '#')
      continue;

    std::string key;
    std::string value;
    if (!string_utils::SplitAtFirst(line, "=", &key, &value, false))
      return false;

    base::TrimWhitespaceASCII(key, base::TRIM_TRAILING, &key);
    if (key.empty())
      return false;

    // Append additional lines to the value as long as we see trailing
    // backslashes.
    while (!value.empty() && value.back() == '\\') {
      ++it;
      if (it == lines.end() || it->empty())
        return false;
      value.pop_back();
      value += *it;
    }

    store_[key] = value;
  }
  return true;
}

bool KeyValueStore::Save(const base::FilePath& path) const {
  return base::ImportantFileWriter::WriteFileAtomically(path, SaveToString());
}

string KeyValueStore::SaveToString() const {
  string data;
  for (const auto& key_value : store_)
    data += key_value.first + "=" + key_value.second + "\n";
  return data;
}

void KeyValueStore::Clear() {
  store_.clear();
}

bool KeyValueStore::GetString(const string& key, string* value) const {
  const auto key_value = store_.find(TrimKey(key));
  if (key_value == store_.end())
    return false;
  *value = key_value->second;
  return true;
}

void KeyValueStore::SetString(const string& key, const string& value) {
  store_[TrimKey(key)] = value;
}

bool KeyValueStore::GetBoolean(const string& key, bool* value) const {
  string string_value;
  if (!GetString(key, &string_value))
    return false;

  if (string_value == kTrueValue) {
    *value = true;
    return true;
  } else if (string_value == kFalseValue) {
    *value = false;
    return true;
  }
  return false;
}

void KeyValueStore::SetBoolean(const string& key, bool value) {
  SetString(key, value ? kTrueValue : kFalseValue);
}

std::vector<std::string> KeyValueStore::GetKeys() const {
  return GetMapKeysAsVector(store_);
}

}  // namespace brillo
