/*
 * 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.druid.sql.calcite.rule;

import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelOptUtil;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.druid.java.util.common.ISE;

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

/**
 * Rule that prunes unused aggregators after a projection.
 */
public class ProjectAggregatePruneUnusedCallRule extends RelOptRule
{
  private static final ProjectAggregatePruneUnusedCallRule INSTANCE = new ProjectAggregatePruneUnusedCallRule();

  private ProjectAggregatePruneUnusedCallRule()
  {
    super(operand(Project.class, operand(Aggregate.class, any())));
  }

  public static ProjectAggregatePruneUnusedCallRule instance()
  {
    return INSTANCE;
  }

  @Override
  public void onMatch(final RelOptRuleCall call)
  {
    final Project project = call.rel(0);
    final Aggregate aggregate = call.rel(1);

    final ImmutableBitSet projectBits = RelOptUtil.InputFinder.bits(project.getChildExps(), null);

    final int fieldCount = aggregate.getGroupCount() + aggregate.getAggCallList().size();
    if (fieldCount != aggregate.getRowType().getFieldCount()) {
      throw new ISE(
          "Expected[%s] to have[%s] fields but it had[%s]",
          aggregate,
          fieldCount,
          aggregate.getRowType().getFieldCount()
      );
    }

    final ImmutableBitSet callsToKeep = projectBits.intersect(
        ImmutableBitSet.range(aggregate.getGroupCount(), fieldCount)
    );

    if (callsToKeep.cardinality() < aggregate.getAggCallList().size()) {
      // There are some aggregate calls to prune.
      final List<AggregateCall> newAggregateCalls = new ArrayList<>();

      for (int i : callsToKeep) {
        newAggregateCalls.add(aggregate.getAggCallList().get(i - aggregate.getGroupCount()));
      }

      final Aggregate newAggregate = aggregate.copy(
          aggregate.getTraitSet(),
          aggregate.getInput(),
          aggregate.getGroupSet(),
          aggregate.getGroupSets(),
          newAggregateCalls
      );

      // Project that will match the old Aggregate in its row type, so we can layer the original "project" on top.
      final List<RexNode> fixUpProjects = new ArrayList<>();
      final RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder();

      // Project the group set unchanged.
      for (int i = 0; i < aggregate.getGroupCount(); i++) {
        fixUpProjects.add(rexBuilder.makeInputRef(newAggregate, i));
      }

      // Replace pruned-out aggregators with NULLs.
      for (int i = aggregate.getGroupCount(), j = aggregate.getGroupCount(); i < fieldCount; i++) {
        if (callsToKeep.get(i)) {
          fixUpProjects.add(rexBuilder.makeInputRef(newAggregate, j++));
        } else {
          fixUpProjects.add(rexBuilder.makeNullLiteral(aggregate.getRowType().getFieldList().get(i).getType()));
        }
      }

      call.transformTo(
          call.builder()
              .push(newAggregate)
              .project(fixUpProjects)
              .project(project.getChildExps())
              .build()
      );

      call.getPlanner().setImportance(project, 0.0);
    }
  }
}
