// 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

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
