/**
 * 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_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_
