/**
 * 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_PARSER_PARSE_PREDICATE_HPP_
#define QUICKSTEP_PARSER_PARSE_PREDICATE_HPP_

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

#include "parser/ParseExpression.hpp"
#include "parser/ParseTreeNode.hpp"
#include "utility/Macros.hpp"
#include "utility/PtrList.hpp"

namespace quickstep {

class Comparison;

/** \addtogroup Parser
 *  @{
 */

/**
 * @brief The parsed representation of a predicate.
 **/
class ParsePredicate : public ParseTreeNode {
 public:
  /**
   * @brief The possible types of ParsePredicates.
   **/
  enum ParsePredicateType {
    kBetween,
    kComparison,
    kNegation,
    kConjunction,
    kDisjunction,
    kExists,
    kInTableQuery,
    kInValueList
  };

  /**
   * @brief Virtual destructor.
   **/
  ~ParsePredicate() override {}

  /**
   * @brief Identify the type of this ParsePredicate.
   *
   * @return The type of this ParsePredicate.
   **/
  virtual ParsePredicateType getParsePredicateType() const = 0;

 protected:
  ParsePredicate(const int line_number, const int column_number)
      : ParseTreeNode(line_number, column_number) {
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ParsePredicate);
};

/**
 * @brief The parsed representation of a simple comparison predicate.
 **/
class ParsePredicateComparison : public ParsePredicate {
 public:
  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the comparison operator token in the SQL statement.
   * @param column_number Column number of the comparison operator token in the SQL statement.
   * @param op The comparison (from the quickstep type system).
   * @param left_operand The left operand of the comparison, which becomes
   *        owned by this ParsePredicateComparison.
   * @param right_operand The right operand of the comparison, which becomes
   *        owned by this ParsePredicateComparison.
   **/
  ParsePredicateComparison(const int line_number,
                           const int column_number,
                           const Comparison &op,
                           ParseExpression *left_operand,
                           ParseExpression *right_operand)
      : ParsePredicate(line_number, column_number),
        op_(op),
        left_operand_(left_operand),
        right_operand_(right_operand) {
  }

  /**
   * @brief Destructor.
   */
  ~ParsePredicateComparison() override {}

  /**
   * @return The comparison operator.
   */
  const Comparison& op() const {
    return op_;
  }

  /**
   * @return The left operand.
   */
  const ParseExpression* left_operand() const {
    return left_operand_.get();
  }

  /**
   * @return The right operand.
   */
  const ParseExpression* right_operand() const {
    return right_operand_.get();
  }

  std::string getName() const override;

  ParsePredicateType getParsePredicateType() const override {
    return kComparison;
  }

 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<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;

 private:
  const Comparison &op_;
  std::unique_ptr<ParseExpression> left_operand_;
  std::unique_ptr<ParseExpression> right_operand_;

  DISALLOW_COPY_AND_ASSIGN(ParsePredicateComparison);
};

/**
 * @brief The parsed representation of a NOT predicate.
 **/
class ParsePredicateNegation : public ParsePredicate {
 public:
  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   * @param operand The inner predicate to be negated, becomes owned by this
   *        ParsePredicateNegation.
   **/
  ParsePredicateNegation(const int line_number, const int column_number, ParsePredicate *operand)
      : ParsePredicate(line_number, column_number), operand_(operand) {
  }

  /**
   * @brief Destructor.
   */
  ~ParsePredicateNegation() override {}

  /**
   * @return The operand.
   */
  const ParsePredicate* operand() const {
    return operand_.get();
  }

  ParsePredicateType getParsePredicateType() const override {
    return kNegation;
  }

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

 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<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;

 private:
  std::unique_ptr<ParsePredicate> operand_;

  DISALLOW_COPY_AND_ASSIGN(ParsePredicateNegation);
};

/**
 * @brief The parsed representation of a BETWEEN predicate.
 *        The parser does not convert it to two comparison
 *        predicates to avoid cloning and evaluating \p middle_operand_
 *        twice for complex expressions (subqueries or
 *        aggregations). The query optimizer is responsible for the conversion.
 **/
class ParsePredicateBetween : public ParsePredicate {
 public:
  /**
   * @brief Construction.
   *
   * @param line_number The line number of 'BETWEEN' in the SQL statement.
   * @param column_number The column number of 'BETWEEN' in the SQL statement.
   * @param lower_bound_operand The operand on the left side of BETWEEN.
   * @param check_operand The operand in between BETWEEN and AND.
   * @param upper_bound_operand The operand after AND.
   */
  ParsePredicateBetween(const int line_number,
                        const int column_number,
                        ParseExpression *check_operand,
                        ParseExpression *lower_bound_operand,
                        ParseExpression *upper_bound_operand)
      : ParsePredicate(line_number, column_number),
        check_operand_(check_operand),
        lower_bound_operand_(lower_bound_operand),
        upper_bound_operand_(upper_bound_operand) {
  }

  /**
   * @brief Destructor.
   */
  ~ParsePredicateBetween() override {}

  /**
   * @return The operand to be compared with the lower bound and
   *         the upper bound.
   */
  const ParseExpression* check_operand() const {
    return check_operand_.get();
  }

  /**
   * @return Lower bound operand.
   */
  const ParseExpression* lower_bound_operand() const {
    return lower_bound_operand_.get();
  }

  /**
   * @return Upper bound operand.
   */
  const ParseExpression* upper_bound_operand() const {
    return upper_bound_operand_.get();
  }

  ParsePredicateType getParsePredicateType() const override {
    return kBetween;
  }

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

 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<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;

 private:
  std::unique_ptr<ParseExpression> check_operand_;
  std::unique_ptr<ParseExpression> lower_bound_operand_;
  std::unique_ptr<ParseExpression> upper_bound_operand_;

  DISALLOW_COPY_AND_ASSIGN(ParsePredicateBetween);
};

/**
 * @brief Abstract base class of conjunction and disjunction predicates.
 **/
class ParsePredicateWithList : public ParsePredicate {
 public:
  ~ParsePredicateWithList() override {}

  const PtrList<ParsePredicate>& operands() const {
    return operands_;
  }

  /**
   * @brief Add a child predicate to this conjunction or disjunction.
   *
   * @param operand The child predicate to add to this one, which becomes
   *        owned by this predicate.
   **/
  void addPredicate(ParsePredicate *operand) {
    operands_.push_back(operand);
  }

 protected:
  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   **/
  ParsePredicateWithList(const int line_number, const int column_number)
      : ParsePredicate(line_number, column_number) {
  }

  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<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;

  PtrList<ParsePredicate> operands_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ParsePredicateWithList);
};

/**
 * @brief An AND over other predicates.
 **/
class ParsePredicateConjunction : public ParsePredicateWithList {
 public:
  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   **/
  ParsePredicateConjunction(const int line_number, const int column_number)
      : ParsePredicateWithList(line_number, column_number) {
  }

  ParsePredicateType getParsePredicateType() const override {
    return kConjunction;
  }

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

 private:
  DISALLOW_COPY_AND_ASSIGN(ParsePredicateConjunction);
};

/**
 * @brief An OR over other predicates.
 **/
class ParsePredicateDisjunction : public ParsePredicateWithList {
 public:
  /**
   * @brief Constructor.
   *
   * @param line_number Line number of the first token of this node in the SQL statement.
   * @param column_number Column number of the first token of this node in the SQL statement.
   **/
  ParsePredicateDisjunction(const int line_number, const int column_number)
      : ParsePredicateWithList(line_number, column_number) {
  }

  ParsePredicateType getParsePredicateType() const override {
    return kDisjunction;
  }

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

 private:
  DISALLOW_COPY_AND_ASSIGN(ParsePredicateDisjunction);
};


/**
 * @brief Parsed representation of IN with a value list.
 */
class ParsePredicateInValueList : public ParsePredicate {
 public:
  /**
   * @brief Constructor.
   *
   * @param line_number The line number of the token "IN" in the statement.
   * @param column_number The column number of the token "IN" in the statement.
   * @param test_expression The expression to be compared with a value list.
   * @param value_list The list of values to match with test_expression.
   */
  ParsePredicateInValueList(const int line_number,
                            const int column_number,
                            ParseExpression *test_expression,
                            PtrList<ParseExpression> *value_list)
      : ParsePredicate(line_number, column_number),
        test_expression_(test_expression),
        value_list_(value_list) {}

  ParsePredicateType getParsePredicateType() const override {
    return kInValueList;
  }

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

  /**
   * @return  The expression to be compared with a value list.
   */
  const ParseExpression* test_expression() const {
    return test_expression_.get();
  }

  /**
   * @return The list of values to match with test_expression.
   */
  const PtrList<ParseExpression>* value_list() const {
    return value_list_.get();
  }

 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<const ParseTreeNode*> *non_container_child_fields,
      std::vector<std::string> *container_child_field_names,
      std::vector<std::vector<const ParseTreeNode*>> *container_child_fields) const override;

 private:
  std::unique_ptr<ParseExpression> test_expression_;
  std::unique_ptr<PtrList<ParseExpression>> value_list_;

  DISALLOW_COPY_AND_ASSIGN(ParsePredicateInValueList);
};

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_PARSER_PARSE_PREDICATE_HPP_
