// Copyright 2017 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.

#ifndef CBOR_VALUES_H_
#define CBOR_VALUES_H_

#include <stdint.h>

#include <string>
#include <tuple>
#include <vector>

#include "base/check.h"
#include "base/containers/flat_map.h"
#include "base/containers/span.h"
#include "base/notreached.h"
#include "base/notreached.h"
#include "base/strings/string_piece.h"
#include "cbor/cbor_export.h"

namespace cbor {

// A class for Concise Binary Object Representation (CBOR) values.
// This does not support:
//  * Floating-point numbers.
//  * Indefinite-length encodings.
class CBOR_EXPORT Value {
 public:
  struct Less {
    // Comparison predicate to order keys in a dictionary as required by the
    // canonical CBOR order defined in
    // https://tools.ietf.org/html/rfc7049#section-3.9
    // TODO(808022): Clarify where this stands.
    bool operator()(const Value& a, const Value& b) const {
      // The current implementation only supports integer, text string, byte
      // string and invalid UTF8 keys.
      DCHECK((a.is_integer() || a.is_string() || a.is_bytestring() ||
              a.is_invalid_utf8()) &&
             (b.is_integer() || b.is_string() || b.is_bytestring() ||
              b.is_invalid_utf8()));

      // Below text from https://tools.ietf.org/html/rfc7049 errata 4409:
      // *  If the major types are different, the one with the lower value
      //    in numerical order sorts earlier.
      if (a.type() != b.type())
        return a.type() < b.type();

      // *  If two keys have different lengths, the shorter one sorts
      //    earlier;
      // *  If two keys have the same length, the one with the lower value
      //    in (byte-wise) lexical order sorts earlier.
      switch (a.type()) {
        case Type::UNSIGNED:
          // For unsigned integers, the smaller value has shorter length,
          // and (byte-wise) lexical representation.
          return a.GetInteger() < b.GetInteger();
        case Type::NEGATIVE:
          // For negative integers, the value closer to zero has shorter length,
          // and (byte-wise) lexical representation.
          return a.GetInteger() > b.GetInteger();
        case Type::STRING: {
          const auto& a_str = a.GetString();
          const size_t a_length = a_str.size();
          const auto& b_str = b.GetString();
          const size_t b_length = b_str.size();
          return std::tie(a_length, a_str) < std::tie(b_length, b_str);
        }
        case Type::BYTE_STRING: {
          const auto& a_str = a.GetBytestring();
          const size_t a_length = a_str.size();
          const auto& b_str = b.GetBytestring();
          const size_t b_length = b_str.size();
          return std::tie(a_length, a_str) < std::tie(b_length, b_str);
        }
        case Type::INVALID_UTF8: {
          const auto& a_str = a.GetInvalidUTF8();
          const size_t a_length = a_str.size();
          const auto& b_str = b.GetInvalidUTF8();
          const size_t b_length = b_str.size();
          return std::tie(a_length, a_str) < std::tie(b_length, b_str);
        }
        default:
          break;
      }

      NOTREACHED();
      return false;
    }

    using is_transparent = void;
  };

  using BinaryValue = std::vector<uint8_t>;
  using ArrayValue = std::vector<Value>;
  using MapValue = base::flat_map<Value, Value, Less>;

  enum class Type {
    UNSIGNED = 0,
    NEGATIVE = 1,
    BYTE_STRING = 2,
    STRING = 3,
    ARRAY = 4,
    MAP = 5,
    TAG = 6,
    SIMPLE_VALUE = 7,
    NONE = -1,
    INVALID_UTF8 = -2,
  };

  enum class SimpleValue {
    FALSE_VALUE = 20,
    TRUE_VALUE = 21,
    NULL_VALUE = 22,
    UNDEFINED = 23,
  };

  // Returns a Value with Type::INVALID_UTF8. This factory method lets tests
  // encode such a value as a CBOR string. It should never be used outside of
  // tests since encoding may yield invalid CBOR data.
  static Value InvalidUTF8StringValueForTesting(base::StringPiece in_string);

  Value(Value&& that) noexcept;
  Value() noexcept;  // A NONE value.

  explicit Value(Type type);

  explicit Value(SimpleValue in_simple);
  explicit Value(bool boolean_value);

  explicit Value(int integer_value);
  explicit Value(int64_t integer_value);
  explicit Value(uint64_t integer_value) = delete;

  explicit Value(base::span<const uint8_t> in_bytes);
  explicit Value(BinaryValue&& in_bytes) noexcept;

  explicit Value(const char* in_string, Type type = Type::STRING);
  explicit Value(std::string&& in_string, Type type = Type::STRING) noexcept;
  explicit Value(base::StringPiece in_string, Type type = Type::STRING);

  explicit Value(const ArrayValue& in_array);
  explicit Value(ArrayValue&& in_array) noexcept;

  explicit Value(const MapValue& in_map);
  explicit Value(MapValue&& in_map) noexcept;

  Value& operator=(Value&& that) noexcept;

  Value(const Value&) = delete;
  Value& operator=(const Value&) = delete;

  ~Value();

  // Value's copy constructor and copy assignment operator are deleted.
  // Use this to obtain a deep copy explicitly.
  Value Clone() const;

  // Returns the type of the value stored by the current Value object.
  Type type() const { return type_; }

  // Returns true if the current object represents a given type.
  bool is_type(Type type) const { return type == type_; }
  bool is_none() const { return type() == Type::NONE; }
  bool is_invalid_utf8() const { return type() == Type::INVALID_UTF8; }
  bool is_simple() const { return type() == Type::SIMPLE_VALUE; }
  bool is_bool() const {
    return is_simple() && (simple_value_ == SimpleValue::TRUE_VALUE ||
                           simple_value_ == SimpleValue::FALSE_VALUE);
  }
  bool is_unsigned() const { return type() == Type::UNSIGNED; }
  bool is_negative() const { return type() == Type::NEGATIVE; }
  bool is_integer() const { return is_unsigned() || is_negative(); }
  bool is_bytestring() const { return type() == Type::BYTE_STRING; }
  bool is_string() const { return type() == Type::STRING; }
  bool is_array() const { return type() == Type::ARRAY; }
  bool is_map() const { return type() == Type::MAP; }

  // These will all fatally assert if the type doesn't match.
  SimpleValue GetSimpleValue() const;
  bool GetBool() const;
  const int64_t& GetInteger() const;
  const int64_t& GetUnsigned() const;
  const int64_t& GetNegative() const;
  const BinaryValue& GetBytestring() const;
  base::StringPiece GetBytestringAsString() const;
  // Returned string may contain NUL characters.
  const std::string& GetString() const;
  const ArrayValue& GetArray() const;
  const MapValue& GetMap() const;
  const BinaryValue& GetInvalidUTF8() const;

 private:
  friend class Reader;
  // This constructor allows INVALID_UTF8 values to be created, which only
  // |Reader| and InvalidUTF8StringValueForTesting() may do.
  Value(base::span<const uint8_t> in_bytes, Type type);

  Type type_;

  union {
    SimpleValue simple_value_;
    int64_t integer_value_;
    BinaryValue bytestring_value_;
    std::string string_value_;
    ArrayValue array_value_;
    MapValue map_value_;
  };

  void InternalMoveConstructFrom(Value&& that);
  void InternalCleanup();
};

}  // namespace cbor

#endif  // CBOR_VALUES_H_
