// Copyright 2019 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 LIBIPP_IPP_ATTRIBUTE_H_
#define LIBIPP_IPP_ATTRIBUTE_H_

#include <cstdint>
#include <limits>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "ipp_enums.h"   // NOLINT(build/include)
#include "ipp_export.h"  // NOLINT(build/include)

namespace ipp {

// Represents the current state of the attribute:
// set/unset or one of the out-of-band values.
// "unset" means that the attribute is not included in a IPP frame.
enum class AttrState : uint8_t {
  unset = 0x00,             // internal
  set = 0x01,               // internal
  unsupported = 0x10,       // [rfc8010]
  unknown = 0x12,           // [rfc8010]
  novalue_ = 0x13,          // [rfc8010]
  not_settable = 0x15,      // [rfc3380]
  delete_attribute = 0x16,  // [rfc3380]
  admin_define = 0x17       // [rfc3380]
};

// Represents types of values hold by attributes (see [rfc8010]).
// "collection" means that the attribute has Collection object as a value.
enum class AttrType : uint8_t {
  integer = 0x21,
  boolean = 0x22,
  enum_ = 0x23,
  octetString = 0x30,
  dateTime = 0x31,
  resolution = 0x32,
  rangeOfInteger = 0x33,
  collection = 0x34,  // use begCollection tag value [rfc8010]
  text = 0x35,        // use textWithLanguage tag value [rfc8010]
  name = 0x36,        // use nameWithLanguage tag value [rfc8010]
  keyword = 0x44,
  uri = 0x45,
  uriScheme = 0x46,
  charset = 0x47,
  naturalLanguage = 0x48,
  mimeMediaType = 0x49
};

// It is used to hold name and text values (see [rfc8010]).
// If language == "" it represents nameWithoutLanguage or textWithoutLanguage,
// otherwise it represents nameWithLanguage or textWithLanguage.
struct StringWithLanguage {
  std::string value = "";
  std::string language = "";
  StringWithLanguage() = default;
  StringWithLanguage(const std::string& value, const std::string& language)
      : value(value), language(language) {}
  explicit StringWithLanguage(const std::string& value) : value(value) {}
  explicit StringWithLanguage(std::string&& value) : value(value) {}
  operator std::string() const { return value; }
};

// Represents resolution type from [rfc8010].
struct Resolution {
  int32_t xres = 0;
  int32_t yres = 0;
  enum Units { kDotsPerInch = 3, kDotsPerCentimeter = 4 } units = kDotsPerInch;
  Resolution() = default;
  Resolution(int32_t size1, int32_t size2, Units units = Units::kDotsPerInch)
      : xres(size1), yres(size2), units(units) {}
};

// Represents rangeOfInteger type from [rfc8010].
struct RangeOfInteger {
  int32_t min_value = 0;
  int32_t max_value = 0;
  RangeOfInteger() = default;
  RangeOfInteger(int32_t min_value, int32_t max_value)
      : min_value(min_value), max_value(max_value) {}
};

// Represents dateTime type from [rfc8010,rfc2579].
struct DateTime {
  uint16_t year = 2000;
  uint8_t month = 1;            // 1..12
  uint8_t day = 1;              // 1..31
  uint8_t hour = 0;             // 0..23
  uint8_t minutes = 0;          // 0..59
  uint8_t seconds = 0;          //  0..60 (60 - leap second :-)
  uint8_t deci_seconds = 0;     // 0..9
  uint8_t UTC_direction = '+';  // '+' / '-'
  uint8_t UTC_hours = 0;        // 0..13
  uint8_t UTC_minutes = 0;      //  0..59
};

// Functions converting basic types to string. For enums it returns empty
// string if given value is not defined.
IPP_EXPORT std::string ToString(AttrState value);
IPP_EXPORT std::string ToString(AttrType value);
IPP_EXPORT std::string ToString(bool value);
IPP_EXPORT std::string ToString(int value);
IPP_EXPORT std::string ToString(const Resolution& value);
IPP_EXPORT std::string ToString(const RangeOfInteger& value);
IPP_EXPORT std::string ToString(const DateTime& value);
IPP_EXPORT std::string ToString(const StringWithLanguage& value);

// Functions extracting basic types from string.
// Returns false <=> given pointer is nullptr or given string does not
// represent a correct value.
IPP_EXPORT bool FromString(const std::string& str, bool* value);
IPP_EXPORT bool FromString(const std::string& str, int* value);

// Basic values are stored in attributes as variables of the following types:
enum InternalType : uint8_t {
  kInteger,             // int32_t
  kString,              // std::string
  kStringWithLanguage,  // ipp::StringWithLanguage
  kResolution,          // ipp::Resolution
  kRangeOfInteger,      // ipp::RangeOfInteger
  kDateTime,            // ipp::DateTime
  kCollection           // Collection*
};

class Attribute;
class Collection;

// Type of function creating new object of class derived from Collection.
typedef Collection* (*CollectionConstructor)();

// Helper structure
struct AttrDef {
  AttrType ipp_type;
  InternalType cc_type;
  bool is_a_set;
  CollectionConstructor constructor = nullptr;
};

// Base class for all IPP collections. Collections is like struct filled with
// Attributes. Each attribute in Collection must have unique name.
class IPP_EXPORT Collection {
 public:
  virtual ~Collection();

  // Returns all attributes in the collection.
  // Returned vector = GetKnownAttributes() + unknown attributes.
  // Unknown attributes are in the order they were added to the collection.
  // There are no nullptrs in the returned vector.
  std::vector<Attribute*> GetAllAttributes();
  std::vector<const Attribute*> GetAllAttributes() const;

  // Methods return attribute by name. Methods return nullptr <=> the collection
  // has no attribute with this name.
  Attribute* GetAttribute(AttrName);
  const Attribute* GetAttribute(AttrName) const;
  Attribute* GetAttribute(const std::string& name);
  const Attribute* GetAttribute(const std::string& name) const;

  // Adds new attribute to the collection. Returns nullptr <=> an attribute
  // with this name already exists in the collection or given name/type are
  // incorrect.
  Attribute* AddUnknownAttribute(const std::string& name,
                                 bool is_a_set,
                                 AttrType type);

 protected:
  explicit Collection(const std::map<AttrName, AttrDef>* defs)
      : definitions_(defs) {}

 private:
  friend class Attribute;
  // Copy/move/assign constructors/operators are forbidden.
  Collection(const Collection&) = delete;
  Collection(Collection&&) = delete;
  Collection& operator=(const Collection&) = delete;
  Collection& operator=(Collection&&) = delete;

  // Methods to implement in derived class, return attributes from schema
  // and their definitions. There is no nullptrs in the returned vector.
  virtual std::vector<Attribute*> GetKnownAttributes() = 0;
  virtual std::vector<const Attribute*> GetKnownAttributes() const = 0;

  // Helper function, an attribute |name| must belong to the collection.
  AttrDef GetAttributeDefinition(AttrName name) const;

  // Helper template function.
  template <typename ApiType>
  bool SaveValue(AttrName name, size_t index, const ApiType& value);

  // Stores a pointer to the attributes definitions. It is set in the
  // constructor by derived classes.
  const std::map<AttrName, AttrDef>* const definitions_;
  // Stores values of the attributes.
  std::map<AttrName, void*> values_;
  // Stores states of the attributes (see AttrState).
  std::map<AttrName, AttrState> states_;

  // Internal structure, represent attributes defined in runtime.
  struct UnknownAttr {
    Attribute* object;
    AttrDef def;
  };
  // Stores attributes defined in runtime.
  std::map<AttrName, UnknownAttr> unknown_attributes;
  // Mapping between temporary AttrName created for unknown attributes and
  // their real names.
  std::map<AttrName, std::string> unknown_names;
};

// Final class for Collection represents collection without known attributes.
class IPP_EXPORT EmptyCollection : public Collection {
 public:
  EmptyCollection() : Collection(&defs_) {}

 private:
  std::vector<Attribute*> GetKnownAttributes() override { return {}; };
  std::vector<const Attribute*> GetKnownAttributes() const override {
    return {};
  };
  static const std::map<AttrName, AttrDef> defs_;  // empty
};

// Base class representing Attribute, contains general API for Attribute.
class IPP_EXPORT Attribute {
 public:
  // Returns a type of the attribute.
  AttrType GetType() const;

  // Returns a state of an attribute. Default state is always AttrState::unset,
  // setting any value with SetValues(...) switches the state to AttrState::set.
  // State can be also set by hand with SetState() method.
  AttrState GetState() const;

  // Sets state of the attribute (set, unset or one of the out-of-band values).
  // * If (new_state != set), it deletes all values stored in the attribute.
  // * If (new_state == set), it adds single value if the attribute is empty.
  void SetState(AttrState new_state);

  // Returns true if the attribute is a set, false if it is a single value.
  bool IsASet() const;

  // Returns enum value corresponding to attributes name. If the name has
  // no corresponding AttrName value, it returns AttrName::_unknown.
  AttrName GetNameAsEnum() const {
    if (offset_ == std::numeric_limits<int16_t>::min() && ToString(name_) == "")
      return AttrName::_unknown;
    return name_;
  }

  // Returns an attribute's name as a non-empty string.
  std::string GetName() const {
    const std::string s = ToString(name_);
    if (!s.empty()) {
      return s;
    }
    const Collection* coll = GetOwner();
    return coll->unknown_names.at(name_);
  }

  // Returns the current number of elements (values or Collections).
  // (IsASet() == false) => always returns 0 or 1.
  size_t GetSize() const;

  // Resizes the attribute (changes the number of stored values/collections).
  // (IsASet() == false) and (new_size > 1) => does nothing.
  // (GetSize() > 0) and (|new_size| == 0) => the attribute's state is changed
  // to AttrState::unset.
  void Resize(size_t new_size);

  // Retrieves a value from an attribute, returns true for success and
  // false if the index is out of range or the value cannot be converted
  // to given variable (in this case, the given variable is not modified).
  // For attributes with collections use GetCollection().
  // (val == nullptr) => does nothing and returns false.
  // (GetType() == collection) => does nothing and returns false.
  bool GetValue(std::string* val, size_t index = 0) const;
  bool GetValue(StringWithLanguage* val, size_t index = 0) const;
  bool GetValue(int* val, size_t index = 0) const;
  bool GetValue(Resolution* val, size_t index = 0) const;
  bool GetValue(RangeOfInteger* val, size_t index = 0) const;
  bool GetValue(DateTime* val, size_t index = 0) const;

  // Stores a value in given attribute's element. If the attribute is a set
  // and given index is out of range, the underlying container is resized.
  // Returns true for success and false if given value cannot be converted
  // to internal variable or one of the following conditions are met:
  // * (GetType() == collection)
  // * (IsASet() == false && index != 0).
  bool SetValue(const std::string& val, size_t index = 0);
  bool SetValue(const StringWithLanguage& val, size_t index = 0);
  bool SetValue(const int& val, size_t index = 0);
  bool SetValue(const Resolution& val, size_t index = 0);
  bool SetValue(const RangeOfInteger& val, size_t index = 0);
  bool SetValue(const DateTime& val, size_t index = 0);

  // Returns a pointer to Collection.
  // (GetType() != collection || index >= GetSize()) <=> returns nullptr.
  Collection* GetCollection(size_t index = 0);
  const Collection* GetCollection(size_t index = 0) const;

 protected:
  // Constructor is available from derived classes only.
  Attribute(Collection* owner, AttrName name);
  // This class has no virtual destructor for a reason. Making this class
  // virtual would increase object's size 3 times (or more). All objects of this
  // class must be deleted by calling a destructor directly from derived class.

  // Returns owner of the attribute. Never returns nullptr.
  Collection* GetOwner() const;

  const int16_t offset_;
  const AttrName name_;

 private:
  // Copy/move/assign constructors/operators are forbidden.
  Attribute(const Attribute&) = delete;
  Attribute(Attribute&&) = delete;
  Attribute& operator=(const Attribute&) = delete;
  Attribute& operator=(Attribute&&) = delete;
};

// These templates convert the type from specialized API to the internal type
// used to store values. Default is integer because it is used for all enum
// types.
template <typename TType>
struct AsInternalType {
  static const InternalType value = InternalType::kInteger;
  typedef int Type;
};
template <>
struct AsInternalType<std::string> {
  static const InternalType value = InternalType::kString;
  typedef std::string Type;
};
template <>
struct AsInternalType<Resolution> {
  static const InternalType value = InternalType::kResolution;
  typedef Resolution Type;
};
template <>
struct AsInternalType<RangeOfInteger> {
  static const InternalType value = InternalType::kRangeOfInteger;
  typedef RangeOfInteger Type;
};
template <>
struct AsInternalType<DateTime> {
  static const InternalType value = InternalType::kDateTime;
  typedef DateTime Type;
};
template <>
struct AsInternalType<StringWithLanguage> {
  static const InternalType value = InternalType::kStringWithLanguage;
  typedef StringWithLanguage Type;
};

// Final class for Attribute, represents single value from the schema.
// Template parameter defines type of the value.
template <typename TValue>
class SingleValue : public Attribute {
 public:
  SingleValue(Collection* owner, AttrName name) : Attribute(owner, name) {}

  // Specialized API
  void Set(const TValue& val) {
    Attribute::SetValue(
        static_cast<typename AsInternalType<TValue>::Type>(val));
  }
  TValue Get() const {
    typename AsInternalType<TValue>::Type val;
    Attribute::GetValue(&val);
    return static_cast<TValue>(val);
  }
};

// Specialization of the template above for StringWithLanguage to add
// Set(std::string).
template <>
class SingleValue<StringWithLanguage> : public Attribute {
 public:
  SingleValue(Collection* owner, AttrName name) : Attribute(owner, name) {}

  // Specialized API
  void Set(const StringWithLanguage& val) { Attribute::SetValue(val); }
  void Set(const std::string& val) {
    Attribute::SetValue(static_cast<StringWithLanguage>(val));
  }
  StringWithLanguage Get() const {
    StringWithLanguage val;
    Attribute::GetValue(&val);
    return val;
  }
};

// Final class for Attribute, represents sets of values.
// Template parameter defines type of a single value.
template <typename TValue>
class SetOfValues : public Attribute {
 public:
  SetOfValues(Collection* owner, AttrName name) : Attribute(owner, name) {}

  // Specialized API
  void Set(const std::vector<TValue>& vals) {
    Resize(vals.size());
    for (size_t i = 0; i < vals.size(); ++i)
      SetValue(vals[i], i);
  }
  std::vector<TValue> Get() const {
    std::vector<TValue> vals(GetSize());
    for (size_t i = 0; i < vals.size(); ++i) {
      typename AsInternalType<TValue>::Type val;
      GetValue(&val, i);
      vals[i] = static_cast<TValue>(val);
    }
    return vals;
  }
  void Add(const std::vector<TValue>& vals) {
    const size_t old_size = GetSize();
    Resize(old_size + vals.size());
    for (size_t i = 0; i < vals.size(); ++i)
      SetValue(vals[i], old_size + i);
  }
};

// Specialization of the template above for StringWithLanguage to add
// Set/Add(std::string).
template <>
class SetOfValues<StringWithLanguage> : public Attribute {
 public:
  SetOfValues(Collection* owner, AttrName name) : Attribute(owner, name) {}

  // Specialized API
  void Set(const std::vector<StringWithLanguage>& vals) {
    Resize(vals.size());
    for (size_t i = 0; i < vals.size(); ++i)
      SetValue(vals[i], i);
  }
  void Set(const std::vector<std::string>& vals) {
    Resize(vals.size());
    for (size_t i = 0; i < vals.size(); ++i)
      SetValue(vals[i], i);
  }
  std::vector<StringWithLanguage> Get() const {
    std::vector<StringWithLanguage> vals(GetSize());
    for (size_t i = 0; i < vals.size(); ++i) {
      StringWithLanguage val;
      GetValue(&val, i);
      vals[i] = val;
    }
    return vals;
  }
  void Add(const std::vector<StringWithLanguage>& vals) {
    const size_t old_size = GetSize();
    Resize(old_size + vals.size());
    for (size_t i = 0; i < vals.size(); ++i)
      SetValue(vals[i], old_size + i);
  }
  void Add(const std::vector<std::string>& vals) {
    const size_t old_size = GetSize();
    Resize(old_size + vals.size());
    for (size_t i = 0; i < vals.size(); ++i)
      SetValue(vals[i], old_size + i);
  }
};

// Final class for Attribute, represents sets of values that can contain names
// outside the schema.
template <typename TValue>
class OpenSetOfValues : public Attribute {
 public:
  OpenSetOfValues(Collection* owner, AttrName name) : Attribute(owner, name) {}

  // Specialized API
  void Set(const std::vector<std::string>& vals) {
    Resize(vals.size());
    for (size_t i = 0; i < vals.size(); ++i)
      SetValue(vals[i], i);
  }
  void Set(const std::vector<TValue>& vals) {
    Resize(vals.size());
    for (size_t i = 0; i < vals.size(); ++i)
      SetValue(ToString(vals[i]), i);
  }
  std::vector<std::string> Get() const {
    std::vector<std::string> vals(GetSize());
    for (size_t i = 0; i < vals.size(); ++i)
      GetValue(&(vals[i]), i);
    return vals;
  }
  void Add(const std::vector<std::string>& vals) {
    const size_t old_size = GetSize();
    Resize(old_size + vals.size());
    for (size_t i = 0; i < vals.size(); ++i)
      SetValue(vals[i], old_size + i);
  }
  void Add(const std::vector<TValue>& vals) {
    const size_t old_size = GetSize();
    Resize(old_size + vals.size());
    for (size_t i = 0; i < vals.size(); ++i)
      SetValue(ToString(vals[i]), old_size + i);
  }
};

// Final class for Attribute, represents single IPP collection.
// Template parameter is a class derived from Collection and defines
// the structure.
template <class TCollection>
class SingleCollection : public Attribute {
 public:
  SingleCollection(Collection* owner, AttrName name) : Attribute(owner, name) {}
  TCollection* operator->() {
    Resize(1);
    return dynamic_cast<TCollection*>(GetCollection());
  }
  // Returns reference to the underlying collection. If the attribute is not
  // set (GetState() != AttrState::set) returns a reference to empty collection.
  const TCollection& Get() const {
    const Collection* coll = GetCollection();
    if (coll == nullptr)
      return TCollection::empty;
    return *(dynamic_cast<const TCollection*>(coll));
  }
};

// Final class for Attribute, represents set of collections from IPP spec.
// Template parameter is a class derived from Collection and defines
// the structure of a single collection.
template <class TCollection>
class SetOfCollections : public Attribute {
 public:
  SetOfCollections(Collection* owner, AttrName name) : Attribute(owner, name) {}
  // If |index| is out of range, the vector is resized to (index+1).
  TCollection& operator[](size_t index) {
    if (GetSize() <= index)
      Resize(index + 1);
    return *(dynamic_cast<TCollection*>(GetCollection(index)));
  }
  // Const version of the method above. If |index| is out of range,
  // a reference to an empty static collection is returned.
  const TCollection& At(size_t index) const {
    const Collection* coll = GetCollection(index);
    if (coll == nullptr)
      return TCollection::empty;
    return *(dynamic_cast<const TCollection*>(coll));
  }
};

}  // namespace ipp

#endif  //  LIBIPP_IPP_ATTRIBUTE_H_
