// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LIBIPP_FRAME_H_
#define LIBIPP_FRAME_H_

#include <array>
#include <cstdint>
#include <utility>
#include <vector>

#include "attribute.h"
#include "colls_view.h"
#include "ipp_enums.h"
#include "ipp_export.h"

namespace ipp {

// represents operation id
typedef E_operations_supported Operation;

// represents status-code [rfc8010]
typedef E_status_code Status;

// represents the version of IPP protocol
// The first byte (MSB) of this value correspond to major version number, the
// second one to minor version number.
typedef E_ipp_versions_supported Version;

// There are methods that return error codes. The error code is usually
// returned via the last method's parameter that is optional.
// This enum contains possible values of error codes.
enum class Code {
  kOK,                 // success (no errors)
  kDataTooLong,        // the payload of the frame is too large
  kInvalidGroupTag,    // provided GroupTag is invalid
  kInvalidValueTag,    // provided ValueTag is invalid
  kIndexOutOfRange,    // parameter 'index' is wrong
  kTooManyGroups,      // reached the threshold
  kTooManyAttributes,  // reached the threshold
  kInvalidName,        // incorrect attribute name
  kNameConflict,       // attribute with this name already exists
  kIncompatibleType,   // conversion between C++ type and value is not supported
  kValueOutOfRange     // given C++ value is out of range (invalid)
};

// The correct values of GroupTag are 0x01, 0x02, 0x04-0x0f. This function
// checks if given GroupTag is valid.
constexpr bool IsValid(GroupTag tag) {
  if (tag > static_cast<GroupTag>(0x0f))
    return false;
  if (tag < static_cast<GroupTag>(0x01))
    return false;
  return (tag != static_cast<GroupTag>(0x03));
}
// This array contains all valid GroupTag values and may be used in loops like
//   for (GroupTag gt: kGroupTags) ...
constexpr std::array<GroupTag, 14> kGroupTags{
    static_cast<GroupTag>(0x01), static_cast<GroupTag>(0x02),
    static_cast<GroupTag>(0x04), static_cast<GroupTag>(0x05),
    static_cast<GroupTag>(0x06), static_cast<GroupTag>(0x07),
    static_cast<GroupTag>(0x08), static_cast<GroupTag>(0x09),
    static_cast<GroupTag>(0x0a), static_cast<GroupTag>(0x0b),
    static_cast<GroupTag>(0x0c), static_cast<GroupTag>(0x0d),
    static_cast<GroupTag>(0x0e), static_cast<GroupTag>(0x0f)};

// TODO(pawliczek) - move all limits to separate header, this one was moved here
//                   from ipp_parser.cc
// This parameters defines maximum number of attribute groups in single package.
constexpr size_t kMaxCountOfAttributeGroups = 20 * 1024;

class Collection;
class Attribute;

// This class represents an IPP frame (IPP request or IPP response). All
// pointers to Collection or Attribute returned by methods of this class
// point to internal objects. These objects are always owned by their Frame
// object and their lifetime does not exceed the lifetime of their owner.
class LIBIPP_EXPORT Frame {
 public:
  // Constructor. Create an empty frame with all basic parameters set to 0.
  Frame();
  // Constructor. Create a frame and set basic parameters for IPP request.
  // If `set_localization_en_us` is true (default) the Group Operation
  // Attributes is added to the frame with two attributes:
  //   * "attributes-charset"="utf-8"
  //   * "attributes-natural-language"="en-us"
  // If `set_localization_en_us` equals false, you have to add the Group
  // Operation Attributes with these two attributes by hand since they are
  // required to be the first attributes in the frame (see section 4.1.4 from
  // RFC 8011).
  explicit Frame(Operation operation_id,
                 Version version_number = Version::_1_1,
                 int32_t request_id = 1,
                 bool set_localization_en_us = true);
  // Constructor. The same as the previous constructor but for IPP response.
  // There is no differences between frames created with this and the previous
  // constructor. IPP requests and IPP responses have the same structure.
  // Values of operation_id and status_code are saved in the same variable,
  // they are just casted to different enums with static_cast<>(). The parameter
  // `set_localization_en_us_and_status_message` works in similar way as the
  // parameter `set_localization_en_us` in the constructor above but also adds
  // the attribute "status-message" to the Group Operation Attributes. The value
  // of the attribute is set to a string representation of the `status_code`.
  // The attribute "status-message" is defined in the section 4.1.6.2 from
  // RFC 8011.
  explicit Frame(Status status_code,
                 Version version_number = Version::_1_1,
                 int32_t request_id = 1,
                 bool set_localization_en_us_and_status_message = true);

  Frame(const Frame&) = delete;
  Frame& operator=(const Frame&) = delete;
  Frame(Frame&&) = default;
  Frame& operator=(Frame&&) = default;
  virtual ~Frame();

  // Access IPP version number.
  Version& VersionNumber();
  Version VersionNumber() const;
  // Access operation id or status code. OperationId() and StatusCode() refer to
  // the same field, they just cast the same value to different enums. The field
  // is interpreted as operation id in IPP request and as status code in IPP
  // responses.
  int16_t& OperationIdOrStatusCode();
  int16_t OperationIdOrStatusCode() const;
  Operation OperationId() const;
  Status StatusCode() const;
  // Access request id.
  int32_t& RequestId();
  int32_t RequestId() const;
  // Access to payload (e.g.: document to print).
  const std::vector<uint8_t>& Data() const;
  // Remove the payload from the frame and return it.
  std::vector<uint8_t> TakeData();
  // Set the new payload in the frame. The returned value is one of:
  //  * Code::kOK
  //  * Code::kDataTooLong
  Code SetData(std::vector<uint8_t>&& data);

  // Provides access to groups with the given GroupTag. You can iterate over
  // these groups in the following way:
  //   for (Collection& coll: frame.Groups(GroupTag::job_attributes)) {
  //     ...
  //   }
  // or
  //   for (size_t i = 0; i < frame.Groups(GroupTag::job_attributes).size(); ) {
  //     Collection& coll = frame.Groups(GroupTag::job_attributes)[i++];
  //     ...
  //   }
  // The groups are in the same order as they occur in the frame.
  CollsView Groups(GroupTag tag);
  ConstCollsView Groups(GroupTag tag) const;

  // Return all groups of attributes in the frame in the order they were added.
  // The returned vector never contains nullptr values.
  std::vector<std::pair<GroupTag, Collection*>> GetGroups();
  std::vector<std::pair<GroupTag, const Collection*>> GetGroups() const;

  // Add a new group of attributes to the frame. The iterator to the new group
  // is saved in `new_group`. The returned iterator is valid in the range
  // returned by Groups(tag).
  // The returned value is one of the following:
  //  * Code::kOK
  //  * Code::kInvalidGroupTag
  //  * Code::kTooManyGroups
  // If the returned value != Code::kOK then `new_group` is not modified.
  Code AddGroup(GroupTag tag, CollsView::iterator& new_group);

 private:
  Version version_;
  int16_t operation_id_or_status_code_;
  int32_t request_id_;
  // Groups stored in the order they appear in the binary representation.
  std::vector<std::pair<GroupTag, Collection*>> groups_;
  // Content of `group_` sorted by GroupTag. The largest valid value of GroupTag
  // is 0x0f (see kGroupTags above).
  std::array<std::vector<Collection*>, 16> groups_by_tag_;
  std::vector<uint8_t> data_;
};

}  // namespace ipp

#endif  //  LIBIPP_FRAME_H_
