/*
 * 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.adapter.enumerable;

import org.apache.calcite.linq4j.Ord;
import org.apache.calcite.linq4j.tree.BlockBuilder;
import org.apache.calcite.linq4j.tree.Expression;
import org.apache.calcite.linq4j.tree.Expressions;
import org.apache.calcite.linq4j.tree.ParameterExpression;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelTraitSet;
import org.apache.calcite.rel.RelCollation;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.Pair;
import org.apache.calcite.util.Util;

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

/** Implementation of {@link org.apache.calcite.rel.core.Union} in
 * {@link org.apache.calcite.adapter.enumerable.EnumerableConvention enumerable calling convention}.
 * Performs a union (or union all) of all its inputs (which must be already sorted),
 * respecting the order. */
public class EnumerableMergeUnion extends EnumerableUnion {

  protected EnumerableMergeUnion(RelOptCluster cluster, RelTraitSet traitSet, List<RelNode> inputs,
      boolean all) {
    super(cluster, traitSet, inputs, all);
    final RelCollation collation = traitSet.getCollation();
    if (collation == null || collation.getFieldCollations().isEmpty()) {
      throw new IllegalArgumentException("EnumerableMergeUnion with no collation");
    }
    for (RelNode input : inputs) {
      final RelCollation inputCollation = input.getTraitSet().getCollation();
      if (inputCollation == null || !inputCollation.satisfies(collation)) {
        throw new IllegalArgumentException("EnumerableMergeUnion input does not satisfy collation. "
            + "EnumerableMergeUnion collation: " + collation + ". Input collation: "
            + inputCollation + ". Input: " + input);
      }
    }
  }

  public static EnumerableMergeUnion create(RelCollation collation, List<RelNode> inputs,
      boolean all) {
    final RelOptCluster cluster = inputs.get(0).getCluster();
    final RelTraitSet traitSet = cluster.traitSetOf(EnumerableConvention.INSTANCE).replace(
        collation);
    return new EnumerableMergeUnion(cluster, traitSet, inputs, all);
  }

  @Override public EnumerableMergeUnion copy(RelTraitSet traitSet, List<RelNode> inputs,
      boolean all) {
    return new EnumerableMergeUnion(getCluster(), traitSet, inputs, all);
  }

  @Override public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
    final BlockBuilder builder = new BlockBuilder();

    final ParameterExpression inputListExp = Expressions.parameter(
        List.class,
        builder.newName("mergeUnionInputs" + Integer.toUnsignedString(this.getId())));
    builder.add(Expressions.declare(0, inputListExp, Expressions.new_(ArrayList.class)));

    for (Ord<RelNode> ord : Ord.zip(inputs)) {
      final EnumerableRel input = (EnumerableRel) ord.e;
      final Result result = implementor.visitChild(this, ord.i, input, pref);
      final Expression childExp = builder.append("child" + ord.i, result.block);
      builder.add(
          Expressions.statement(
              Expressions.call(inputListExp, BuiltInMethod.COLLECTION_ADD.method, childExp)));
    }

    final PhysType physType = PhysTypeImpl.of(
        implementor.getTypeFactory(),
        getRowType(),
        pref.prefer(JavaRowFormat.CUSTOM));

    final RelCollation collation = getTraitSet().getCollation();
    if (collation == null || collation.getFieldCollations().isEmpty()) {
      // should not happen
      throw new IllegalStateException("EnumerableMergeUnion with no collation");
    }
    final Pair<Expression, Expression> pair =
        physType.generateCollationKey(collation.getFieldCollations());
    final Expression sortKeySelector = pair.left;
    final Expression sortComparator = pair.right;

    final Expression equalityComparator = Util.first(
        physType.comparer(),
        Expressions.call(BuiltInMethod.IDENTITY_COMPARER.method));

    final Expression unionExp = Expressions.call(
        BuiltInMethod.MERGE_UNION.method,
        inputListExp,
        sortKeySelector,
        sortComparator,
        Expressions.constant(all, boolean.class),
        equalityComparator);
    builder.add(unionExp);

    return implementor.result(physType, builder.toBlock());
  }
}
