/**
 * 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_QUERY_OPTIMIZER_PHYSICAL_SELECTION_HPP_
#define QUICKSTEP_QUERY_OPTIMIZER_PHYSICAL_SELECTION_HPP_

#include <memory>
#include <string>
#include <vector>

#include "query_optimizer/OptimizerTree.hpp"
#include "query_optimizer/expressions/AttributeReference.hpp"
#include "query_optimizer/expressions/ExpressionUtil.hpp"
#include "query_optimizer/expressions/NamedExpression.hpp"
#include "query_optimizer/expressions/LogicalAnd.hpp"
#include "query_optimizer/expressions/Predicate.hpp"
#include "query_optimizer/physical/Physical.hpp"
#include "query_optimizer/physical/PhysicalType.hpp"
#include "utility/Macros.hpp"

namespace quickstep {
namespace optimizer {
namespace physical {

/** \addtogroup OptimizerPhysical
 *  @{
 */

struct PartitionSchemeHeader;

class Selection;
typedef std::shared_ptr<const Selection> SelectionPtr;

/**
 * @brief Physical node that evaluates a predicate for each input tuple,
 *        computes and outputs the values of project expressions if the
 *        predicate evaluates to true.
 */
class Selection : public Physical {
 public:
  PhysicalType getPhysicalType() const override { return PhysicalType::kSelection; }

  std::string getName() const override { return "Selection"; }

  /**
   * @return Filter predicate to evaluate during scanning the input.
   */
  inline const expressions::PredicatePtr& filter_predicate() const {
    return filter_predicate_;
  }

  /**
   * @return Project expressions to compute.
   */
  inline const std::vector<expressions::NamedExpressionPtr>& project_expressions() const {
    return project_expressions_;
  }

  /**
   * @return Input physical node.
   */
  inline const PhysicalPtr& input() const { return children()[0]; }

  PhysicalPtr copyWithNewChildren(
      const std::vector<PhysicalPtr> &new_children) const override;

  std::vector<expressions::AttributeReferencePtr> getOutputAttributes() const override;

  std::vector<expressions::AttributeReferencePtr> getReferencedAttributes() const override;

  PhysicalPtr copyWithNewOutputPartitionSchemeHeader(
      PartitionSchemeHeader *partition_scheme_header) const override {
    return Create(input(), project_expressions_, filter_predicate_, partition_scheme_header);
  }

  bool maybeCopyWithPrunedExpressions(
      const expressions::UnorderedNamedExpressionSet &referenced_attributes,
      PhysicalPtr *output) const override;

  /**
   * @brief Creates a Selection.
   *
   * @param input The input node.
   * @param project_expressions The project expressions.
   * @param filter_predicate The filter predicate. Can be NULL.
   * @param output_partition_scheme_header The partition scheme header that
   *        overwrites that from input, if not NULL. It takes ownership of
   *        'output_partition_scheme_header'.
   *
   * @return An immutable Selection.
   */
  static SelectionPtr Create(
      const PhysicalPtr &input,
      const std::vector<expressions::NamedExpressionPtr> &project_expressions,
      const expressions::PredicatePtr &filter_predicate,
      PartitionSchemeHeader *output_partition_scheme_header = nullptr) {
    return SelectionPtr(
        new Selection(input, project_expressions, filter_predicate, output_partition_scheme_header));
  }

  /**
   * @brief Creates a conjunctive predicate with \p filter_predicates
   *        as operands, and creates a Selection with the predicate.
   *
   * @param input The input node.
   * @param project_expressions The project expressions.
   * @param filter_predicates A list of filter predicates.
   *                          The predicate in the created Selection is
   *                          a conjunction of them.
   * @return An immutable Selection.
   */
  static SelectionPtr CreateWithConjuction(
      const PhysicalPtr &input,
      const std::vector<expressions::NamedExpressionPtr> &project_expressions,
      const std::vector<expressions::PredicatePtr> &filter_predicates) {
    if (filter_predicates.size() > 1u) {
      return Create(input, project_expressions,
                    expressions::LogicalAnd::Create(filter_predicates));
    } else if (filter_predicates.size() == 1u) {
      return Create(input, project_expressions, filter_predicates[0]);
    } else {
      return Create(input, project_expressions, expressions::PredicatePtr());
    }
  }

 protected:
  void getFieldStringItems(
      std::vector<std::string> *inline_field_names,
      std::vector<std::string> *inline_field_values,
      std::vector<std::string> *non_container_child_field_names,
      std::vector<OptimizerTreeBaseNodePtr> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<OptimizerTreeBaseNodePtr>> *container_child_fields) const override;

 private:
  Selection(
      const PhysicalPtr &input,
      const std::vector<expressions::NamedExpressionPtr> &project_expressions,
      const expressions::PredicatePtr &filter_predicate,
      PartitionSchemeHeader *partition_scheme_header)
      : Physical(partition_scheme_header),
        project_expressions_(project_expressions),
        filter_predicate_(filter_predicate) {
    addChild(input);
  }

  const std::vector<expressions::NamedExpressionPtr> project_expressions_;
  // Can be NULL. If NULL, the filter predicate is treated as the literal true.
  const expressions::PredicatePtr filter_predicate_;

  DISALLOW_COPY_AND_ASSIGN(Selection);
};

/** @} */

}  // namespace physical
}  // namespace optimizer
}  // namespace quickstep

#endif /* QUICKSTEP_QUERY_OPTIMIZER_PHYSICAL_SELECTION_HPP_ */
