// 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 "fides/key.h"

#include <algorithm>

#include <base/logging.h>

namespace fides {

namespace {

bool IsValidKeyComponentChar(char c) {
  // This corresponds to the set of valid chars in C identifiers.
  //
  // NB: Dashes ('-', i.e. ASCII code 0x2d) are not allowed. That way, all
  // permitted characters sort after '.', which results in prefixes appearing
  // before all matching suffixes in lexicographic sort order. This is helpful
  // when keys and prefixes are used in STL containers such as std::set and
  // std::map.
  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
         (c >= '0' && c <= '9') || c == '_';
}

std::string JoinComponents(std::initializer_list<std::string> components) {
  auto component = components.begin();
  if (component == components.end())
    return std::string();

  std::string result = *component;
  for (++component; component != components.end(); ++component) {
    result += ".";
    result += *component;
  }

  return result;
}

}  // namespace

// static
bool Key::IsValidKey(const std::string& key_string) {
  if (key_string.empty())
    return true;

  bool last_char_was_dot = true;
  for (std::string::value_type c : key_string) {
    if (c == '.') {
      // Don't allow successive dots, i.e. empty components.
      if (last_char_was_dot)
        return false;
      last_char_was_dot = true;
    } else {
      if (!IsValidKeyComponentChar(c))
        return false;
      last_char_was_dot = false;
    }
  }

  return !last_char_was_dot;
}

Key::Key(const std::string& key) : key_(key) {
  CHECK(IsValidKey(key_));
}

Key::Key(std::initializer_list<std::string> components)
  : Key(JoinComponents(components)) {}

bool Key::operator<(const Key& rhs) const {
  return key_ < rhs.key_;
}

bool Key::operator<=(const Key& rhs) const {
  return key_ <= rhs.key_;
}

bool Key::operator==(const Key& rhs) const {
  return key_ == rhs.key_;
}

bool Key::operator!=(const Key& rhs) const {
  return key_ != rhs.key_;
}

const std::string& Key::ToString() const {
  return key_;
}

Key Key::GetParent() const {
  size_t position = key_.rfind('.');
  if (position == std::string::npos)
    return Key();
  return Key(key_.substr(0u, position));
}

Key Key::Append(const Key& other) const {
  if (other.IsRootKey())
    return *this;

  if (IsRootKey())
    return other;

  return Key(key_ + "." + other.key_);
}

Key Key::Extend(std::initializer_list<std::string> components) const {
  return Append(Key(JoinComponents(components)));
}

Key Key::Split(Key* suffix) const {
  const size_t end = key_.find('.');

  // N.B.: Construct the return value before assigning to |suffix|, because
  // |suffix| might be |this|, so assigning |*suffix| may clobber |key_|.
  Key return_value;
  if (end == std::string::npos) {
    return_value = *this;
    if (suffix)
      *suffix = Key();
  } else {
    return_value = Key(key_.substr(0, end));
    if (suffix)
      *suffix = Key(key_.substr(end + 1));
  }

  return return_value;
}

Key Key::CommonPrefix(const Key& other) const {
  Key common_prefix;
  Key this_suffix = *this;
  Key other_suffix = other;

  while (true) {
    Key this_prefix = this_suffix.Split(&this_suffix);
    Key other_prefix = other_suffix.Split(&other_suffix);
    if (this_prefix.IsRootKey() || this_prefix != other_prefix)
      break;
    common_prefix = common_prefix.Append(this_prefix);
  }

  return common_prefix;
}

bool Key::Suffix(const Key& prefix, Key* suffix) const {
  DCHECK(suffix);

  if (prefix.IsRootKey()) {
    *suffix = *this;
    return true;
  }

  if (!prefix.IsPrefixOf(*this))
    return false;

  *suffix = Key(key_.substr(std::min(key_.size(), prefix.key_.size() + 1)));
  return true;
}

Key Key::PrefixUpperBound() const {
  return Key(key_ + '0');
}

bool Key::IsRootKey() const {
  return key_.empty();
}

bool Key::IsPrefixOf(const Key& other) const {
  return *this == CommonPrefix(other);
}

}  // namespace fides
