// 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_PACKAGE_H_
#define LIBIPP_IPP_PACKAGE_H_

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

#include <cstdint>
#include <map>
#include <string>
#include <vector>

namespace ipp {

class Group;

// This class represents IPP frame. It is container for Groups that represent
// IPP attributes groups (like operation-attributes). Groups in a single Package
// must have unique tags (names).
class IPP_EXPORT Package {
 public:
  // destructor
  virtual ~Package();

  // Returns vector of all groups in the package, all pointers are != nullptr.
  // Returned vector = GetKnownGroups() + vector with unknown groups.
  std::vector<Group*> GetAllGroups();
  std::vector<const Group*> GetAllGroups() const;

  // Returns pointer to the group with given tag.
  // Returns nullptr if there is no group with given tag in the package.
  Group* GetGroup(GroupTag);
  const Group* GetGroup(GroupTag) const;

  // Adds a new group to the package and returns pointer to it or nullptr if
  // a group with given tag already exists in the package.
  Group* AddUnknownGroup(GroupTag, bool is_a_set);

  // Returns reference to payload (e.g. document to print), empty vector means
  // no payload.
  std::vector<uint8_t>& Data() { return data_; }
  const std::vector<uint8_t>& Data() const { return data_; }

 protected:
  Package() = default;

 private:
  // Copy/move/assign constructors/operators are not available.
  Package(const Package&) = delete;
  Package(Package&&) = delete;
  Package& operator=(const Package&) = delete;
  Package& operator=(Package&&) = delete;

  // Returns vector with groups in the schema, all pointers are != nullptr.
  // This method must be overloaded in derived classes with schema.
  virtual std::vector<Group*> GetKnownGroups() { return {}; }
  virtual std::vector<const Group*> GetKnownGroups() const { return {}; }

  std::vector<Group*> unknown_groups_;
  std::vector<uint8_t> data_;
};

// Defined later in this file.
class Collection;

// Base class represents single IPP attribute group or a sequence of the
// same IPP attribute groups. Single instance of IPP attribute groups is
// represented by Collection object.
class IPP_EXPORT Group {
 public:
  virtual ~Group() { Resize(0); }

  // Returns tag of the group.
  GroupTag GetName() const { return name_; }

  // Returns true if it is a sequence of IPP groups (Collections) or false
  // if it is a single IPP group (one Collection).
  bool IsASet() const { return is_a_set_; }

  // Returns the current number of elements (IPP groups) in the Group.
  // (IsASet() == false) => always returns 1.
  size_t GetSize() const { return groups_.size(); }

  // Resizes a sequence of IPP groups.
  // Does nothing if (IsASet() == false) and (|new_size| > 0).
  void Resize(size_t new_size) {
    if (!is_a_set_ && new_size > 1)
      return;
    while (new_size < groups_.size()) {
      delete groups_.back();
      groups_.pop_back();
    }
    while (new_size > groups_.size()) {
      groups_.push_back(CreateCollection());
    }
  }

  // Returns a pointer to underlying collection, representing one of the IPP
  // groups. Returns nullptr <=> (index >= GetSize()).
  Collection* GetCollection(size_t index = 0) {
    if (index >= groups_.size())
      return nullptr;
    return groups_[index];
  }
  const Collection* GetCollection(size_t index = 0) const {
    if (index >= groups_.size())
      return nullptr;
    return groups_.at(index);
  }

 protected:
  Group(GroupTag name, bool is_a_set) : name_(name), is_a_set_(is_a_set) {}

 private:
  virtual Collection* CreateCollection() = 0;
  GroupTag name_;
  bool is_a_set_;
  std::vector<Collection*> groups_;
};

// Final class for Groups, represents Group with single IPP attribute group
// defined in the schema. Template parameter TCollection must be a class
// derived from Collection and defines the structure of the group.
template <class TCollection>
class SingleGroup : public Group {
 public:
  explicit SingleGroup(GroupTag name) : Group(name, false) {}
  // Allows to refer to fields in the underlying collection.
  // Creates the collection if it not exists.
  TCollection* operator->() {
    Resize(1);
    return dynamic_cast<TCollection*>(GetCollection());
  }
  // Returns reference to the underlying collection. If the group is empty
  // (GetSize() == 0) returns a reference to an empty static collection.
  const TCollection& Get() const {
    const Collection* coll = GetCollection();
    if (coll == nullptr)
      return TCollection::empty;
    return *(dynamic_cast<const TCollection*>(coll));
  }

 private:
  Collection* CreateCollection() override { return new TCollection; }
};

// Final class for Group, represents sequence of IPP attribute groups with
// the same tag and defined in the schema. Template parameter TCollection is
// a class derived from Collection and defines the structure of a single group.
template <class TCollection>
class SetOfGroups : public Group {
 public:
  explicit SetOfGroups(GroupTag name) : Group(name, true) {}
  // 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));
  }

 private:
  Collection* CreateCollection() override { return new TCollection; }
};

// Final class for Group, represents Group not defined in the schema.
class UnknownGroup : public Group {
 public:
  UnknownGroup(GroupTag name, bool is_a_set) : Group(name, is_a_set) {}

 private:
  Collection* CreateCollection() override { return new EmptyCollection; }
};

}  // namespace ipp

#endif  //  LIBIPP_IPP_PACKAGE_H_
