package edu.uci.ics.asterix.optimizer.rules;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
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.LogicalExpressionTag;
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.expressions.VariableReferenceExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractBinaryJoinOperator;
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.InnerJoinOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.visitors.VariableUtilities;
import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorPropertiesUtil;
import edu.uci.ics.hyracks.algebricks.core.rewriter.base.IAlgebraicRewriteRule;



public class PushGroupByThroughProduct implements IAlgebraicRewriteRule {

    private enum PushTestResult {
        FALSE, TRUE, REPEATED_DECORS
    }

    @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 op1 = (AbstractLogicalOperator) opRef.getValue();
        if (op1.getOperatorTag() != LogicalOperatorTag.GROUP) {
            return false;
        }
        Mutable<ILogicalOperator> opRef2 = op1.getInputs().get(0);
        AbstractLogicalOperator op2 = (AbstractLogicalOperator) opRef2.getValue();
        if (op2.getOperatorTag() != LogicalOperatorTag.INNERJOIN) {
            return false;
        }
        InnerJoinOperator join = (InnerJoinOperator) op2;
        if (!OperatorPropertiesUtil.isAlwaysTrueCond(join.getCondition().getValue())) {
            // not a product
            return false;
        }
        GroupByOperator gby = (GroupByOperator) op1;

        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorToPush = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();
        List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorNotToPush = new ArrayList<Pair<LogicalVariable, Mutable<ILogicalExpression>>>();

        Mutable<ILogicalOperator> opLeftRef = join.getInputs().get(0);
        ILogicalOperator opLeft = opLeftRef.getValue();
        switch (canPushThrough(gby, opLeft, decorToPush, decorNotToPush)) {
            case REPEATED_DECORS: {
                return false;
            }
            case TRUE: {
                push(opRef, opRef2, 0, decorToPush, decorNotToPush, context);
                return true;
            }
            case FALSE: {
                decorToPush.clear();
                Mutable<ILogicalOperator> opRightRef = join.getInputs().get(1);
                ILogicalOperator opRight = opRightRef.getValue();
                if (canPushThrough(gby, opRight, decorToPush, decorNotToPush) == PushTestResult.TRUE) {
                    push(opRef, opRef2, 1, decorToPush, decorNotToPush, context);
                    return true;
                } else {
                    return false;
                }
            }
            default: {
                throw new IllegalStateException();
            }
        }
    }

    private void push(Mutable<ILogicalOperator> opRefGby, Mutable<ILogicalOperator> opRefJoin, int branch,
            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorToPush,
            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> decorNotToPush, IOptimizationContext context)
            throws AlgebricksException {
        GroupByOperator gby = (GroupByOperator) opRefGby.getValue();
        AbstractBinaryJoinOperator join = (AbstractBinaryJoinOperator) opRefJoin.getValue();
        gby.getDecorList().clear();
        gby.getDecorList().addAll(decorToPush);
        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : decorNotToPush) {
            LogicalVariable v1 = p.first;
            VariableReferenceExpression varRef = (VariableReferenceExpression) p.second.getValue();
            LogicalVariable v2 = varRef.getVariableReference();
            OperatorManipulationUtil.substituteVarRec(join, v2, v1, true, context);
        }
        Mutable<ILogicalOperator> branchRef = join.getInputs().get(branch);
        ILogicalOperator opBranch = branchRef.getValue();
        opRefJoin.setValue(opBranch);
        branchRef.setValue(gby);
        opRefGby.setValue(join);
    }

    private PushTestResult canPushThrough(GroupByOperator gby, ILogicalOperator branch,
            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> toPush,
            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> notToPush) throws AlgebricksException {
        Collection<LogicalVariable> fromBranch = new HashSet<LogicalVariable>();
        VariableUtilities.getLiveVariables(branch, fromBranch);
        Collection<LogicalVariable> usedInGbyExprList = new ArrayList<LogicalVariable>();
        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getGroupByList()) {
            p.second.getValue().getUsedVariables(usedInGbyExprList);
        }

        if (!fromBranch.containsAll(usedInGbyExprList)) {
            return PushTestResult.FALSE;
        }
        Set<LogicalVariable> free = new HashSet<LogicalVariable>();
        for (ILogicalPlan p : gby.getNestedPlans()) {
            for (Mutable<ILogicalOperator> r : p.getRoots()) {
                OperatorPropertiesUtil.getFreeVariablesInSelfOrDesc((AbstractLogicalOperator) r.getValue(), free);
            }
        }
        if (!fromBranch.containsAll(free)) {
            return PushTestResult.FALSE;
        }

        Set<LogicalVariable> decorVarRhs = new HashSet<LogicalVariable>();
        decorVarRhs.clear();
        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> p : gby.getDecorList()) {
            ILogicalExpression expr = p.second.getValue();
            if (expr.getExpressionTag() != LogicalExpressionTag.VARIABLE) {
                return PushTestResult.FALSE;
            }
            VariableReferenceExpression varRef = (VariableReferenceExpression) expr;
            LogicalVariable v = varRef.getVariableReference();
            if (decorVarRhs.contains(v)) {
                return PushTestResult.REPEATED_DECORS;
            }
            decorVarRhs.add(v);

            if (fromBranch.contains(v)) {
                toPush.add(p);
            } else {
                notToPush.add(p);
            }
        }
        return PushTestResult.TRUE;
    }
}
