/**
 *   Copyright 2011-2015 Quickstep Technologies LLC.
 *   Copyright 2015 Pivotal Software, Inc.
 *
 *   Licensed 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/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();
  }

 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_
