/**
 * 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_NEGATION_PREDICATE_HPP_
#define QUICKSTEP_EXPRESSIONS_PREDICATE_NEGATION_PREDICATE_HPP_

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

#include "catalog/CatalogTypedefs.hpp"
#include "expressions/Expressions.pb.h"
#include "expressions/predicate/Predicate.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "utility/Macros.hpp"

namespace quickstep {

class Expression;
class TupleIdSequence;
class ValueAccessor;

struct SubBlocksReference;

/** \addtogroup Expressions
 *  @{
 */

/**
 * @brief A negation of another Predicate.
 **/
class NegationPredicate : public Predicate {
 public:
  /**
   * @brief Constructor.
   * @note The static factory method NegatePredicate (which is able to simplify
   *       away double-negations) should be used instead of this constructor in
   *       most cases.
   *
   * @param operand The Predicate which will be negated, becomes owned by this
   *        NegationPredicate.
   **/
  explicit NegationPredicate(Predicate *operand):
    operand_(operand) {
    initHelper();
  }

  /**
   * @brief Destructor which also deletes the operand.
   **/
  ~NegationPredicate() override {
  }

  /**
   * @brief Static method to obtain the negated form of a Predicate. This
   *        should be used instead of invoking NegationPredicate's constructor,
   *        as it allows double-negations to be simplified away.
   *
   * @param operand The Predicate to negate. Caller relinquishes ownership of
   *        operand by calling this method.
   * @return The negative of operand.
   **/
  static Predicate* NegatePredicate(Predicate *operand);

  serialization::Predicate getProto() const override;

  Predicate* clone() const override;

  PredicateType getPredicateType() const override {
    return kNegation;
  }

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

  bool matchesForJoinedTuples(
      const ValueAccessor &left_accessor,
      const relation_id left_relation_id,
      const tuple_id left_tuple_id,
      const ValueAccessor &right_accessor,
      const relation_id right_relation_id,
      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 has_static_result_;
  }

  bool getStaticResult() const override;

 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:
  void initHelper();

  std::unique_ptr<Predicate> operand_;

  bool has_static_result_;
  bool static_result_;

  friend class PredicateTest;

  DISALLOW_COPY_AND_ASSIGN(NegationPredicate);
};

/** @} */

}  // namespace quickstep

#endif  // QUICKSTEP_EXPRESSIONS_PREDICATE_NEGATION_PREDICATE_HPP_
