/**
 * 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.
 **/

#include "query_optimizer/strategy/Selection.hpp"

#include <map>
#include <memory>
#include <unordered_set>
#include <vector>

#include "query_optimizer/LogicalToPhysicalMapper.hpp"
#include "query_optimizer/OptimizerContext.hpp"
#include "query_optimizer/expressions/AttributeReference.hpp"
#include "query_optimizer/expressions/ExprId.hpp"
#include "query_optimizer/expressions/ExpressionUtil.hpp"
#include "query_optimizer/expressions/NamedExpression.hpp"
#include "query_optimizer/expressions/Predicate.hpp"
#include "query_optimizer/logical/Filter.hpp"
#include "query_optimizer/logical/Logical.hpp"
#include "query_optimizer/logical/PatternMatcher.hpp"
#include "query_optimizer/logical/Project.hpp"
#include "query_optimizer/physical/PartitionSchemeHeader.hpp"
#include "query_optimizer/physical/PatternMatcher.hpp"
#include "query_optimizer/physical/Physical.hpp"
#include "query_optimizer/physical/Selection.hpp"
#include "query_optimizer/rules/RuleHelper.hpp"
#include "utility/Cast.hpp"
#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {
namespace optimizer {
namespace strategy {

namespace E = ::quickstep::optimizer::expressions;
namespace L = ::quickstep::optimizer::logical;
namespace P = ::quickstep::optimizer::physical;

bool Selection::generatePlan(const L::LogicalPtr &logical_input,
                             P::PhysicalPtr *physical_output) {
  L::FilterPtr logical_filter;
  L::ProjectPtr logical_project;

  if (L::SomeProject::MatchesWithConditionalCast(logical_input, &logical_project)) {
    E::PredicatePtr filter_predicate;
    L::LogicalPtr logical_input_after_collapse = logical_project->input();
    // Collapse Project and Filter.
    if (L::SomeFilter::MatchesWithConditionalCast(logical_input_after_collapse, &logical_filter)) {
      logical_input_after_collapse = logical_filter->input();
      filter_predicate = logical_filter->filter_predicate();
    }
    addSelection(logical_input_after_collapse, filter_predicate,
                 logical_project->project_expressions(), physical_output);
    return true;
  } else if (L::SomeFilter::MatchesWithConditionalCast(logical_input, &logical_filter)) {
    addSelection(
        logical_filter->input(), logical_filter->filter_predicate(),
        CastSharedPtrVector<E::NamedExpression>(logical_filter->getOutputAttributes()),
        physical_output);
    return true;
  }

  return false;
}

void Selection::addSelection(
    const L::LogicalPtr &logical_input_in,
    const E::PredicatePtr &filter_predicate_in,
    const std::vector<E::NamedExpressionPtr> &project_expressions_in,
    P::PhysicalPtr *physical_output) {
  DCHECK(!project_expressions_in.empty());

  P::PhysicalPtr physical_input =
      physical_mapper_->createOrGetPhysicalFromLogical(logical_input_in);

  E::PredicatePtr filter_predicate = filter_predicate_in;
  std::vector<E::NamedExpressionPtr> project_expressions =
      project_expressions_in;

  P::SelectionPtr child_selection;
  // Pull up the child Selection.
  if (P::SomeSelection::MatchesWithConditionalCast(physical_input, &child_selection)) {
    std::vector<E::ExpressionPtr> new_filter_predicates;
    if (filter_predicate != nullptr) {
      new_filter_predicates.push_back(filter_predicate);
    }

    E::PredicatePtr child_filter_predicate =
        child_selection->filter_predicate();
    physical_input = child_selection->input();
    PullUpProjectExpressions(
        child_selection->project_expressions(),
        {&new_filter_predicates} /* non_project_expressions */,
        {&project_expressions} /* project_expressions */);

    if (filter_predicate != nullptr) {
      CHECK(E::SomePredicate::MatchesWithConditionalCast(new_filter_predicates[0],
                                                         &filter_predicate))
          << new_filter_predicates[0]->toString();
      if (child_filter_predicate != nullptr) {
        filter_predicate = E::LogicalAnd::Create(
            {filter_predicate, child_filter_predicate} /* operands */);
      }
    } else {
      filter_predicate = child_filter_predicate;
    }
  }

  std::unique_ptr<P::PartitionSchemeHeader> physical_output_partition_scheme_header;
  const P::PartitionSchemeHeader *physical_input_partition_scheme_header =
      physical_input->getOutputPartitionSchemeHeader();
  if (physical_input_partition_scheme_header) {
    std::unordered_set<E::ExprId> project_expr_ids;
    for (const E::NamedExpressionPtr &project_expression : project_expressions) {
      project_expr_ids.insert(project_expression->id());
    }

    if (physical_input_partition_scheme_header->reusablePartitionScheme(project_expr_ids)) {
      physical_output_partition_scheme_header =
          std::make_unique<P::PartitionSchemeHeader>(*physical_input_partition_scheme_header);
    }
  }

  *physical_output = P::Selection::Create(physical_input, project_expressions,
                                          filter_predicate, physical_output_partition_scheme_header.release());
}

}  // namespace strategy
}  // namespace optimizer
}  // namespace quickstep
