/*
 * Copyright 2009-2010 by The Regents of the University of California
 * Licensed 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 from
 * 
 *     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 edu.uci.ics.hyracks.algebricks.rewriter.rules;

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang3.mutable.Mutable;

import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
import edu.uci.ics.hyracks.algebricks.common.utils.Pair;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalPlan;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.IOptimizationContext;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalOperatorTag;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalVariable;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.OrderOperator.IOrder;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.AbstractPhysicalOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.physical.StableSortPOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;

public class PushNestedOrderByUnderPreSortedGroupByRule implements IAlgebraicRewriteRule {

    @Override
    public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
        return false;
    }

    @Override
    public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
            throws AlgebricksException {
        AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
        if (op.getOperatorTag() != LogicalOperatorTag.GROUP) {
            return false;
        }
        if (op.getPhysicalOperator() == null) {
            return false;
        }
        AbstractPhysicalOperator pOp = (AbstractPhysicalOperator) op.getPhysicalOperator();
        if (pOp.getOperatorTag() != PhysicalOperatorTag.PRE_CLUSTERED_GROUP_BY) {
            return false;
        }
        GroupByOperator gby = (GroupByOperator) op;
        ILogicalPlan plan = gby.getNestedPlans().get(0);
        AbstractLogicalOperator op1 = (AbstractLogicalOperator) plan.getRoots().get(0).getValue();
        if (op1.getOperatorTag() != LogicalOperatorTag.AGGREGATE) {
            return false;
        }
        Mutable<ILogicalOperator> opRef2 = op1.getInputs().get(0);
        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
        if (op2.getOperatorTag() != LogicalOperatorTag.ORDER) {
            return false;
        }
        OrderOperator order1 = (OrderOperator) op2;
        if (!isIndependentFromChildren(order1)) {
            return false;
        }
        AbstractPhysicalOperator pOrder1 = (AbstractPhysicalOperator) op2.getPhysicalOperator();
        if (pOrder1.getOperatorTag() != PhysicalOperatorTag.STABLE_SORT
                && pOrder1.getOperatorTag() != PhysicalOperatorTag.IN_MEMORY_STABLE_SORT) {
            return false;
        }
        // StableSortPOperator sort1 = (StableSortPOperator) pOrder1;
        AbstractLogicalOperator op3 = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
        if (op3.getOperatorTag() != LogicalOperatorTag.ORDER) {
            return false;
        }
        AbstractPhysicalOperator pOp3 = (AbstractPhysicalOperator) op3.getPhysicalOperator();
        if (pOp3.getOperatorTag() != PhysicalOperatorTag.STABLE_SORT) {
            return false;
        }
        OrderOperator order2 = (OrderOperator) op3;
        StableSortPOperator sort2 = (StableSortPOperator) pOp3;
        // int n1 = sort1.getSortColumns().length;
        // int n2 = sort2.getSortColumns().length;
        // OrderColumn[] sortColumns = new OrderColumn[n2 + n1];
        // System.arraycopy(sort2.getSortColumns(), 0, sortColumns, 0, n2);
        // int k = 0;
        for (Pair<IOrder, Mutable<ILogicalExpression>> oe : order1.getOrderExpressions()) {
            order2.getOrderExpressions().add(oe);
            // sortColumns[n2 + k] = sort1.getSortColumns()[k];
            // ++k;
        }
        // sort2.setSortColumns(sortColumns);
        sort2.computeDeliveredProperties(order2, null);
        // remove order1
        ILogicalOperator underOrder1 = order1.getInputs().get(0).getValue();
        opRef2.setValue(underOrder1);
        return true;
    }

    private boolean isIndependentFromChildren(OrderOperator order1) throws AlgebricksException {
        Set<LogicalVariable> free = new HashSet<LogicalVariable>();
        OperatorPropertiesUtil.getFreeVariablesInSelfOrDesc(order1, free);
        Set<LogicalVariable> usedInOrder = new HashSet<LogicalVariable>();
        VariableUtilities.getUsedVariables(order1, usedInOrder);
        return free.containsAll(usedInOrder);
    }

}
