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

package org.apache.impala.planner;

import org.apache.impala.analysis.Analyzer;
import org.apache.impala.common.InternalException;
import org.apache.impala.thrift.TExplainLevel;
import org.apache.impala.thrift.TPlanNode;
import org.apache.impala.thrift.TPlanNodeType;
import org.apache.impala.thrift.TQueryOptions;

import com.google.common.base.Preconditions;

/**
 * A SubplanNode evaluates its right child plan tree for every row from its left child,
 * and returns those rows produced by the right child. The right child is called the
 * 'subplan tree' and the left child the 'input'. A SubplanNode is similar to a join,
 * but different in the following respects. First, a SubplanNode does not do any real
 * work itself. It only returns rows produced by the right child plan tree, which
 * typically has a dependency on the current input row (see SingularRowSrcNode and
 * UnnestNode). Second, no join predicates are required. A SubplanNode does not
 * evaluate any conjuncts.
 */
public class SubplanNode extends PlanNode {
  private PlanNode subplan_;

  public SubplanNode(PlanNode input) {
    super("SUBPLAN");
    children_.add(input);
  }

  /**
   * Sets the subplan of this SubplanNode. Dependent plan nodes such as UnnestNodes
   * and SingularRowSrcNodes need to know their SubplanNode parent, therefore, setting
   * the subplan in this SubplanNode is deferred until the subplan tree has been
   * constructed (which requires the parent SubplanNode to have been constructed).
   */
  public void setSubplan(PlanNode subplan) {
    Preconditions.checkState(children_.size() == 1);
    subplan_ = subplan;
    children_.add(subplan);
    computeTupleIds();
  }

  @Override
  public void computeTupleIds() {
    Preconditions.checkNotNull(subplan_);
    clearTupleIds();
    tblRefIds_.addAll(subplan_.getTblRefIds());
    tupleIds_.addAll(subplan_.getTupleIds());
    nullableTupleIds_.addAll(subplan_.getNullableTupleIds());
  }

  @Override
  public void init(Analyzer analyzer) throws InternalException {
    // Subplan root must have been set.
    Preconditions.checkState(children_.size() == 2);
    // Check that there are no unassigned conjuncts that can be evaluated by this node.
    // All such conjuncts should have already been assigned in the right child.
    assignConjuncts(analyzer);
    Preconditions.checkState(conjuncts_.isEmpty());
    computeStats(analyzer);
    outputSmap_ = getChild(1).getOutputSmap();
    // Save state of assigned conjuncts for join-ordering attempts (see member comment).
    assignedConjuncts_ = analyzer.getAssignedConjuncts();
  }

  @Override
  protected void computeStats(Analyzer analyzer) {
    super.computeStats(analyzer);
    if (getChild(0).cardinality_ != -1 && getChild(1).cardinality_ != -1) {
      cardinality_ =
          checkedMultiply(getChild(0).cardinality_, getChild(1).cardinality_);
    } else {
      cardinality_ = -1;
    }
    cardinality_ = capAtLimit(cardinality_);
  }

  @Override
  public void computeNodeResourceProfile(TQueryOptions queryOptions) {
    // TODO: add an estimate
    nodeResourceProfile_ = ResourceProfile.noReservation(0);
  }

  @Override
  public ExecPhaseResourceProfiles computeTreeResourceProfiles(
      TQueryOptions queryOptions) {
    // All nodes in a subplan remain open at the same time across iterations of a subplan,
    // therefore the peak resource consumption is simply the sum of all node resources.
    ResourceProfile subplanProfile = subplanComputePeakResources(this);
    return new ExecPhaseResourceProfiles(subplanProfile, subplanProfile);
  }

  private static ResourceProfile subplanComputePeakResources(PlanNode node) {
    ResourceProfile result = node.nodeResourceProfile_;
    for (PlanNode child: node.getChildren()) {
      result = result.sum(subplanComputePeakResources(child));
    }
    return result;
  }

  @Override
  protected String getNodeExplainString(String prefix, String detailPrefix,
      TExplainLevel detailLevel) {
    StringBuilder output = new StringBuilder();
    output.append(String.format("%s%s\n", prefix, getDisplayLabel()));
    if (detailLevel.ordinal() >= TExplainLevel.STANDARD.ordinal()) {
      if (!conjuncts_.isEmpty()) {
        output.append(detailPrefix + "predicates: " +
            getExplainString(conjuncts_) + "\n");
      }
    }
    return output.toString();
  }

  @Override
  protected void toThrift(TPlanNode msg) { msg.node_type = TPlanNodeType.SUBPLAN_NODE; }
}
