/**
 * 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_EXPRESSIONS_PREDICATE_COMPARISON_PREDICATE_HPP_
#define QUICKSTEP_EXPRESSIONS_PREDICATE_COMPARISON_PREDICATE_HPP_

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

#include "catalog/CatalogTypedefs.hpp"
#include "expressions/Expressions.pb.h"
#include "expressions/predicate/Predicate.hpp"
#include "expressions/scalar/Scalar.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "types/operations/comparisons/Comparison.hpp"
#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {

class Expression;
class TupleIdSequence;
class ValueAccessor;

struct SubBlocksReference;

/** \addtogroup Expressions
 *  @{
 */

/**
 * @brief A Predicate which is a comparison of two scalar values.
 **/
class ComparisonPredicate : public Predicate {
 public:
  /**
   * @brief Constructor
   *
   * @param Comparison The comparison operation to be performed.
   * @param left_operand The left argument of the comparison, becomes owned by
   *        this ComparisonPredicate.
   * @param right_operand The right argument of the comparison, becomes owned
   *        by this ComparisonPredicate.
   **/
  ComparisonPredicate(const Comparison &comparison,
                      Scalar *left_operand,
                      Scalar *right_operand);

  ~ComparisonPredicate() override {
  }

  serialization::Predicate getProto() const override;

  Predicate* clone() const override;

  PredicateType getPredicateType() const override {
    return kComparison;
  }

  bool isAttributeLiteralComparisonPredicate() const override;

  bool matchesForSingleTuple(const ValueAccessor &accessor,
                             const tuple_id tuple) const override;

  bool matchesForJoinedTuples(
      const ValueAccessor &left_accessor,
      const tuple_id left_tuple_id,
      const ValueAccessor &right_accessor,
      const tuple_id right_tuple_id) const override;

  TupleIdSequence* getAllMatches(ValueAccessor *accessor,
                                 const SubBlocksReference *sub_blocks_ref,
                                 const TupleIdSequence *filter,
                                 const TupleIdSequence *existence_map) const override;

  bool hasStaticResult() const override {
    return (fast_comparator_.get() == nullptr);
  }

  bool getStaticResult() const override;

  /**
   * @brief Get the comparison operation for this predicate.
   *
   * @return This predicate's comparison.
   **/
  const Comparison& getComparison() const {
    return comparison_;
  }

  /**
   * @brief Get the left operand of this comparison.
   *
   * @return This comparison's left operand.
   **/
  const Scalar& getLeftOperand() const {
    DCHECK(left_operand_.get() != nullptr);
    return *left_operand_;
  }

  /**
   * @brief Get the right operand of this comparison.
   *
   * @return This comparison's right operand.
   **/
  const Scalar& getRightOperand() const {
    DCHECK(right_operand_.get() != nullptr);
    return *right_operand_;
  }

  /**
   * @brief For an attribute-literal comparison, determine whether the
   *        attribute is on the left and what its attribute_id is.
   * @warning This is only usable if isAttributeLiteralComparisonPredicate() is
   *          true.
   *
   * @return A pair: first is true if attribute is on the left, false if on the
   *         right. second is the ID of the attribute.
   **/
  std::pair<bool, attribute_id> getAttributeFromAttributeLiteralComparison() const;

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

 private:
  const Comparison &comparison_;
  std::unique_ptr<Scalar> left_operand_;
  std::unique_ptr<Scalar> right_operand_;
  bool static_result_;
  std::unique_ptr<UncheckedComparator> fast_comparator_;

  void initHelper(bool own_children);

  DISALLOW_COPY_AND_ASSIGN(ComparisonPredicate);
};

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_EXPRESSIONS_PREDICATE_COMPARISON_PREDICATE_HPP_
