/*
 * 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.calcite.rel.rules;

import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelRule;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Sort;
import org.apache.calcite.rel.core.Union;
import org.apache.calcite.rel.metadata.RelMdUtil;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.tools.RelBuilderFactory;

import org.immutables.value.Value;

import java.util.ArrayList;
import java.util.List;

/**
 * Planner rule that pushes a {@link org.apache.calcite.rel.core.Sort} past a
 * {@link org.apache.calcite.rel.core.Union}.
 *
 * @see CoreRules#SORT_UNION_TRANSPOSE
 * @see CoreRules#SORT_UNION_TRANSPOSE_MATCH_NULL_FETCH
 */
@Value.Enclosing
public class SortUnionTransposeRule
    extends RelRule<SortUnionTransposeRule.Config>
    implements TransformationRule {

  /** Creates a SortUnionTransposeRule. */
  protected SortUnionTransposeRule(Config config) {
    super(config);
  }

  @Deprecated // to be removed before 2.0
  public SortUnionTransposeRule(
      Class<? extends Sort> sortClass,
      Class<? extends Union> unionClass,
      boolean matchNullFetch,
      RelBuilderFactory relBuilderFactory,
      String description) {
    this(Config.DEFAULT.withRelBuilderFactory(relBuilderFactory)
        .withDescription(description)
        .as(Config.class)
        .withOperandFor(sortClass, unionClass)
        .withMatchNullFetch(matchNullFetch));
  }

  // ~ Methods ----------------------------------------------------------------

  @Override public boolean matches(RelOptRuleCall call) {
    final Sort sort = call.rel(0);
    final Union union = call.rel(1);
    // We only apply this rule if Union.all is true and Sort.offset is null.
    // There is a flag indicating if this rule should be applied when
    // Sort.fetch is null.
    return union.all
        && sort.offset == null
        && (config.matchNullFetch() || sort.fetch != null);
  }

  @Override public void onMatch(RelOptRuleCall call) {
    final Sort sort = call.rel(0);
    final Union union = call.rel(1);
    List<RelNode> inputs = new ArrayList<>();
    // Thus we use 'ret' as a flag to identify if we have finished pushing the
    // sort past a union.
    boolean ret = true;
    final RelMetadataQuery mq = call.getMetadataQuery();
    for (RelNode input : union.getInputs()) {
      if (!RelMdUtil.checkInputForCollationAndLimit(mq, input,
          sort.getCollation(), sort.offset, sort.fetch)) {
        ret = false;
        Sort branchSort = sort.copy(sort.getTraitSet(), input,
            sort.getCollation(), sort.offset, sort.fetch);
        inputs.add(branchSort);
      } else {
        inputs.add(input);
      }
    }
    // there is nothing to change
    if (ret) {
      return;
    }
    // create new union and sort
    Union unionCopy = (Union) union
        .copy(union.getTraitSet(), inputs, union.all);
    Sort result = sort.copy(sort.getTraitSet(), unionCopy, sort.getCollation(),
        sort.offset, sort.fetch);
    call.transformTo(result);
  }

  /** Rule configuration. */
  @Value.Immutable
  public interface Config extends RelRule.Config {
    Config DEFAULT = ImmutableSortUnionTransposeRule.Config.of()
        .withOperandFor(Sort.class, Union.class)
        .withMatchNullFetch(false);

    @Override default SortUnionTransposeRule toRule() {
      return new SortUnionTransposeRule(this);
    }

    /** Whether to match a Sort whose {@link Sort#fetch} is null. Generally
     * this only makes sense if the Union preserves order (and merges). */
    @Value.Default default boolean matchNullFetch() {
      return false;
    }

    /** Sets {@link #matchNullFetch()}. */
    Config withMatchNullFetch(boolean matchNullFetch);

    /** Defines an operand tree for the given classes. */
    default Config withOperandFor(Class<? extends Sort> sortClass,
        Class<? extends Union> unionClass) {
      return withOperandSupplier(b0 ->
          b0.operand(sortClass).oneInput(b1 ->
              b1.operand(unionClass).anyInputs()))
          .as(Config.class);
    }
  }
}
