/**
 *   Copyright 2011-2015 Quickstep Technologies LLC.
 *   Copyright 2015 Pivotal Software, Inc.
 *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
 *     University of Wisconsin—Madison.
 *
 *   Licensed 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_LOGICAL_HASH_JOIN_HPP_
#define QUICKSTEP_QUERY_OPTIMIZER_LOGICAL_HASH_JOIN_HPP_

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

#include "query_optimizer/OptimizerTree.hpp"
#include "query_optimizer/expressions/AttributeReference.hpp"
#include "query_optimizer/expressions/ExpressionUtil.hpp"
#include "query_optimizer/expressions/Predicate.hpp"
#include "query_optimizer/logical/BinaryJoin.hpp"
#include "query_optimizer/logical/Logical.hpp"
#include "query_optimizer/logical/LogicalType.hpp"
#include "utility/Cast.hpp"
#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {
namespace optimizer {
namespace logical {

/** \addtogroup OptimizerLogical
 *  @{
 */

class HashJoin;
typedef std::shared_ptr<const HashJoin> HashJoinPtr;

/**
 * @brief Hash join operator. It takes two relations and a single equality
 *        predicate between a pair of attributes from each input relation as input,
 *        scans one relation and probes the hash table on the other relation.
 */
class HashJoin : public BinaryJoin {
 public:
  enum class JoinType {
    kInnerJoin = 0,
    kLeftSemiJoin,
    kLeftAntiJoin,
    kLeftOuterJoin
  };

  LogicalType getLogicalType() const override { return LogicalType::kHashJoin; }

  std::string getName() const override {
    switch (join_type_) {
      case JoinType::kInnerJoin:
        return "HashJoin";
      case JoinType::kLeftSemiJoin:
        return "HashLeftSemiJoin";
      case JoinType::kLeftAntiJoin:
        return "HashLeftAntiJoin";
      case JoinType::kLeftOuterJoin:
        return "HashLeftOuterJoin";
      default:
        LOG(FATAL) << "Invalid JoinType: "
                   << static_cast<typename std::underlying_type<JoinType>::type>(join_type_);
    }
  }

  /**
   * @brief Join attributes in the left logical 'left_'.
   */
  const std::vector<expressions::AttributeReferencePtr>& left_join_attributes() const {
    return left_join_attributes_;
  }

  /**
   * @brief Join attributes in the right logical 'right_'.
   */
  const std::vector<expressions::AttributeReferencePtr>& right_join_attributes() const {
    return right_join_attributes_;
  }

  /**
   * @brief The filtering predicate evaluated after join.
   */
  const expressions::PredicatePtr& residual_predicate() const {
    return residual_predicate_;
  }

  /**
   * @return Join type of this hash join.
   */
  JoinType join_type() const {
    return join_type_;
  }

  LogicalPtr copyWithNewChildren(
      const std::vector<LogicalPtr> &new_children) const override {
    DCHECK_EQ(new_children.size(), children().size());
    return HashJoin::Create(new_children[0],
                            new_children[1],
                            left_join_attributes_,
                            right_join_attributes_,
                            residual_predicate_,
                            join_type_);
  }

  std::vector<expressions::AttributeReferencePtr> getOutputAttributes() const override {
    if (join_type_ != JoinType::kLeftOuterJoin) {
      return BinaryJoin::getOutputAttributes();
    }

    // For left outer join, all the output attributes from the right relation
    // must be nullable.
    std::vector<expressions::AttributeReferencePtr> output_attributes =
        left()->getOutputAttributes();
    const std::vector<expressions::AttributeReferencePtr> right_nullable_output_attributes =
        GetNullableAttributeVector(right()->getOutputAttributes());
    output_attributes.insert(output_attributes.end(),
                             right_nullable_output_attributes.begin(),
                             right_nullable_output_attributes.end());
    return output_attributes;
  }

  std::vector<expressions::AttributeReferencePtr> getReferencedAttributes() const override {
    std::vector<expressions::AttributeReferencePtr> referenced_attributes =
        left_join_attributes_;
    referenced_attributes.insert(referenced_attributes.end(),
                                 right_join_attributes_.begin(),
                                 right_join_attributes_.end());
    if (residual_predicate_ != nullptr) {
      const std::vector<expressions::AttributeReferencePtr> referenced_attributes_in_residual =
          residual_predicate_->getReferencedAttributes();
      referenced_attributes.insert(referenced_attributes.end(),
                                   referenced_attributes_in_residual.begin(),
                                   referenced_attributes_in_residual.end());
    }
    return referenced_attributes;
  }

  /**
   * @brief Creates a logical HashJoin operator that combines two relations
   *        produced by the two input operator using join predicate. The node
   *        does not specify which one of the two relations is the build or
   *        the probe relation. The join predicate is the conjunction of
   *        equality predicates for pairs in left_join_attributes and
   *        right_join_attributes.
   *
   * @param left The left input operator.
   * @param right The right input operator.
   * @param left_join_attributes The join attributes in the 'left'.
   * @param right_join_attributes The join attributes in the 'right'.
   * @param Join type of this hash join.
   * @return An immutable HashJoin.
   */
  static HashJoinPtr Create(const LogicalPtr &left,
                            const LogicalPtr &right,
                            const std::vector<expressions::AttributeReferencePtr> &left_join_attributes,
                            const std::vector<expressions::AttributeReferencePtr> &right_join_attributes,
                            const expressions::PredicatePtr &residual_predicate,
                            const JoinType join_type) {
    return HashJoinPtr(
        new HashJoin(left,
                     right,
                     left_join_attributes,
                     right_join_attributes,
                     residual_predicate,
                     join_type));
  }

 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 {
    BinaryJoin::getFieldStringItems(inline_field_names,
                                    inline_field_values,
                                    non_container_child_field_names,
                                    non_container_child_fields,
                                    container_child_field_names,
                                    container_child_fields);

    if (residual_predicate_ != nullptr) {
      non_container_child_field_names->push_back("residual_predicate");
      non_container_child_fields->push_back(residual_predicate_);
    }

    container_child_field_names->push_back("left_join_attributes");
    container_child_fields->push_back(CastSharedPtrVector<OptimizerTreeBase>(left_join_attributes_));
    container_child_field_names->push_back("right_join_attributes");
    container_child_fields->push_back(CastSharedPtrVector<OptimizerTreeBase>(right_join_attributes_));
  }

 private:
  HashJoin(const LogicalPtr &left,
           const LogicalPtr &right,
           const std::vector<expressions::AttributeReferencePtr> &left_join_attributes,
           const std::vector<expressions::AttributeReferencePtr> &right_join_attributes,
           const expressions::PredicatePtr &residual_predicate,
           const JoinType join_type)
      : BinaryJoin(left, right),
        left_join_attributes_(left_join_attributes),
        right_join_attributes_(right_join_attributes),
        residual_predicate_(residual_predicate),
        join_type_(join_type) {
    DCHECK_EQ(left_join_attributes.size(), right_join_attributes.size());
    DCHECK(!left_join_attributes.empty() || residual_predicate != nullptr);

    if (residual_predicate_ != nullptr) {
      addInputExpression(residual_predicate_);
    }
  }

  std::vector<expressions::AttributeReferencePtr> left_join_attributes_;
  std::vector<expressions::AttributeReferencePtr> right_join_attributes_;
  expressions::PredicatePtr residual_predicate_;
  const JoinType join_type_;

  DISALLOW_COPY_AND_ASSIGN(HashJoin);
};

/** @} */

}  // namespace logical
}  // namespace optimizer
}  // namespace quickstep

#endif /* QUICKSTEP_QUERY_OPTIMIZER_LOGICAL_HASH_JOIN_HPP_ */
