/**
 *   Copyright 2011-2015 Quickstep Technologies LLC.
 *   Copyright 2015-2016 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_UTILITY_SORTCONFIGURATION_HPP_
#define QUICKSTEP_UTILITY_SORTCONFIGURATION_HPP_

#include <utility>
#include <vector>

#include "expressions/scalar/Scalar.hpp"
#include "utility/PtrVector.hpp"

namespace quickstep {

class CatalogDatabaseLite;

namespace serialization { class SortConfiguration; }

constexpr bool kSortAscending = true;
constexpr bool kSortDescending = false;
constexpr bool kSortNullLast = false;
constexpr bool kSortNullFirst = true;

/**
 * @brief Sort configuration of a query. Sort configuration is specified by
 * ORDER BY columns, their sort ordering (ascending/descending), and their NULL
 * value ordering (first/last).
 **/
class SortConfiguration {
 public:
  /**
   * @brief Constructor for sort configuration.
   *
   * @param order_by Vector of ORDER BY columns specified as Scalars.
   * @param sort_is_ascending Vector of bools to indicate if sort ordering of
   *        each ORDER BY column is ascending.
   * @param sort_null_first Vector of bools to indicate if NULL value ordering of
   *        each ORDER BY column is first.
   **/
  SortConfiguration(const PtrVector<Scalar> &order_by,
                    std::vector<bool> &&sort_is_ascending,
                    std::vector<bool> &&sort_null_first)
      : ordering_(std::move(sort_is_ascending)),
        null_ordering_(std::move(sort_null_first)) {
    for (const Scalar &order_by_entry : order_by) {
      order_by_.push_back(order_by_entry.clone());
    }
  }

  /**
   * @brief Copy Constructor for sort configuration.
   *
   * @param sort_config Sort configuration to copy from.
   **/
  SortConfiguration(const SortConfiguration &sort_config)
      : ordering_(sort_config.getOrdering()), null_ordering_(sort_config.getNullOrdering()) {
    for (const Scalar &order_by_entry : sort_config.getOrderByList()) {
      order_by_.push_back(order_by_entry.clone());
    }
  }

  /**
   * @brief Get a pointer to a SortConfiguration from its serialized Protocol
   *        Buffer form.
   *
   * @param proto The Protocol Buffer representation of a SortConfiguration
   *        object, originally generated by the optimizer.
   * @param database The Database to resolve relation and attribute references
   *        in.
   *
   * @return A new SortConfiguration reconstructed from the supplied Protocol
   *         Buffer.
   **/
  static SortConfiguration* ReconstructFromProto(const serialization::SortConfiguration &proto,
                                                 const CatalogDatabaseLite &database);

  /**
   * @brief Check whether a serialization::SortConfiguration is fully-formed and
   *        all parts are valid.
   *
   * @param proto A serialized Protocol Buffer representation of a
   *        SortConfiguration, originally generated by the optimizer.
   * @param database The Database to resolve relation and attribute references
   *        in.
   *
   * @return Whether proto is fully-formed and valid.
   **/
  static bool ProtoIsValid(const serialization::SortConfiguration &proto,
                           const CatalogDatabaseLite &database);

  /**
   * @brief Get the vector of sort ordering for each ORDER BY column.
   **/
  inline const std::vector<bool>& getOrdering() const { return ordering_; }

  /**
   * @brief Get the vector of NULL value ordering for each ORDER BY column.
   **/
  inline const std::vector<bool>& getNullOrdering() const { return null_ordering_; }

  /**
   * @brief Get the vector of ORDER BY column Scalars.
   **/
  inline const PtrVector<Scalar>& getOrderByList() const { return order_by_; }

  /**
   * @brief Check if the sort configuration is valid.
   **/
  inline bool isValid() const {
    return (order_by_.size() == ordering_.size()) && (order_by_.size() == null_ordering_.size());
  }

  /**
   * @brief Get serialized protobuf of sort configuration.
   **/
  serialization::SortConfiguration getProto() const;

 private:
  std::vector<bool> ordering_;
  std::vector<bool> null_ordering_;
  PtrVector<Scalar> order_by_;
};

}  // namespace quickstep

#endif  // QUICKSTEP_UTILITY_SORTCONFIGURATION_HPP_
