/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 **/

#ifndef QUICKSTEP_TYPES_CONTAINERS_TUPLE_HPP_
#define QUICKSTEP_TYPES_CONTAINERS_TUPLE_HPP_

#include <cstddef>
#include <memory>
#include <utility>
#include <vector>

#include "catalog/CatalogTypedefs.hpp"
#include "types/TypedValue.hpp"
#include "types/containers/Tuple.pb.h"
#include "utility/CompositeHash.hpp"
#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {

/** \addtogroup Types
 *  @{
 */

/**
 * @brief A representation of a single tuple, i.e. a list of values
 *        corresponding to the attributes of a relation.
 **/
class Tuple {
 public:
  typedef std::vector<TypedValue>::const_iterator const_iterator;
  typedef std::vector<TypedValue>::size_type size_type;

  /**
   * @brief Constructor which creates a Tuple by taking ownership of existing
   *        TypedValues.
   *
   * @param attribute_values A vector of TypedValues, which are the attribute
   *        values, in order, of the Tuple to be constructed. Will be moved
   *        from.
   **/
  explicit Tuple(std::vector<TypedValue> &&attribute_values)
      : attribute_values_(std::move(attribute_values)) {
  }

  /**
   * @brief Move constructor.
   **/
  Tuple(Tuple &&original)
      : attribute_values_(std::move(original.attribute_values_)) {
  }

  /**
   * @brief Destructor.
   **/
  ~Tuple() {
  }

  /**
   * @brief Check whether a serialization::Tuple is fully-formed and all parts
   *        are valid.
   *
   * @param proto A serialized Protocol Buffer description of a Tuple,
   *        originally generated by the optimizer.
   *
   * @return Whether proto is fully-formed and valid.
   **/
  static bool ProtoIsValid(const serialization::Tuple &proto) {
    for (int i = 0; i < proto.attribute_values_size(); ++i) {
      if (!TypedValue::ProtoIsValid(proto.attribute_values(i))) {
        return false;
      }
    }

    return true;
  }

  /**
   * @brief Generate the tuple from the serialized Protocol Buffer
   *        representation.
   *
   * @param proto A serialized Protocol Buffer representation of a Tuple,
   *        originally generated by the optimizer.
   *
   * @return The generated Tuple.
   **/
  static Tuple* ReconstructFromProto(const serialization::Tuple &proto) {
    DCHECK(ProtoIsValid(proto))
        << "Attempted to create Tuple from an invalid proto description:\n"
        << proto.DebugString();

    std::vector<TypedValue> attribute_values;
    for (int i = 0; i < proto.attribute_values_size(); ++i) {
      attribute_values.emplace_back(TypedValue::ReconstructFromProto(proto.attribute_values(i)));
    }

    return new Tuple(std::move(attribute_values));
  }

  /**
   * @brief Move-assignment.
   **/
  Tuple& operator=(Tuple &&other) {
    if (&other != this) {
      attribute_values_ = std::move(other.attribute_values_);
    }
    return *this;
  }

  /**
   * @brief Ensure that every value contained in this tuple is a literal,
   *        copying references as neccesary.
   **/
  void ensureLiteral() {
    for (std::vector<TypedValue>::iterator value_it = attribute_values_.begin();
         value_it != attribute_values_.end();
         ++value_it) {
      value_it->ensureNotReference();
    }
  }

  /**
   * @brief Make a complete copy of this Tuple, forcing a literal copy of each
   *        attribute value.
   *
   * @return A deep copy of this Tuple.
   **/
  Tuple* clone() const {
    std::unique_ptr<Tuple> clone(new Tuple());
    clone->attribute_values_ = attribute_values_;
    clone->ensureLiteral();
    return clone.release();
  }

  /**
   * @brief Get the value of the specified attribute.
   * @warning This is only safe if gapsInAttributeSequence() is false for the
   *          relation this tuple belongs to.
   *
   * @param attr The id of the attribute to get.
   * @return The attribute's value in this tuple.
   **/
  const TypedValue& getAttributeValue(const attribute_id attr) const {
    DCHECK_GE(attr, 0);
    // The cast supresses a warning about comparing signed and unsigned types.
    DCHECK_LT(static_cast<std::vector<TypedValue>::size_type>(attr), attribute_values_.size());
    return attribute_values_[attr];
  }

  /**
   * @brief Get the attribute values vector of the tuple.
   * @warning This is only safe if gapsInAttributeSequence() is false for the
   *          relation this tuple belongs to.
   * @return The attribute values vector of this tuple.
   **/
  const std::vector<TypedValue>& getAttributeValueVector() const {
    return attribute_values_;
  }

  /**
   * @brief Get the total size, in bytes, of all values in this Tuple.
   * @note This method returns the sum of the storage space necessary to store
   *       all attribute values in this Tuple, NOT the space actually used to
   *       represent them at TypedValues.
   *
   * @return The storage size of this Tuple in bytes.
   **/
  std::size_t getByteSize() const {
    std::size_t total_size = 0;
    for (const_iterator it = begin(); it != end(); ++it) {
      total_size += it->isNull() ? 0 : it->getDataSize();
    }
    return total_size;
  }

  /**
   * @brief Get an iterator at the beginning of the attribute values in this
   *        Tuple.
   *
   * @return An iterator at the beginning of this Tuple.
   **/
  const_iterator begin() const {
    return attribute_values_.begin();
  }

  /**
   * @brief Get an iterator one-past-the-end of the attribute values in this
   *        Tuple.
   *
   * @return An iterator one-past-the-end of this Tuple.
   **/
  const_iterator end() const {
    return attribute_values_.end();
  }

  /**
   * @brief Get the number of attributes in this Tuple.
   *
   * @return The number of attributes in this Tuple.
   **/
  size_type size() const {
    return attribute_values_.size();
  }

  /**
   * @brief Get the hash value of the tuple.
   **/
  std::size_t getTupleHash() const {
    return HashCompositeKey(attribute_values_);
  }

 private:
  /**
   * @brief Constructor which does not create any attributes, nor pre-reserve
   *        space.
   * @warning This is only used by clone(), and should not otherwise be used.
   **/
  Tuple() {
  }

  std::vector<TypedValue> attribute_values_;

  DISALLOW_COPY_AND_ASSIGN(Tuple);
};

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_TYPES_CONTAINERS_TUPLE_HPP_
