/*
 * 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.core.algebra.operators.logical.visitors;

import java.util.ArrayList;
import java.util.List;

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.common.utils.Triple;
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.LogicalVariable;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AssignOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.DataSourceScanOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.DieOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.DistinctOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.DistributeResultOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.EmptyTupleSourceOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ExchangeOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ExtensionOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.GroupByOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.IndexInsertDeleteOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.InnerJoinOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.InsertDeleteOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LeftOuterJoinOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.LimitOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator;
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.PartitioningSplitOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ProjectOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ReplicateOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.RunningAggregateOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.ScriptOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SelectOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SinkOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.SubplanOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnionAllOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestMapOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.UnnestOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.WriteResultOperator;
import edu.uci.ics.hyracks.algebricks.core.algebra.typing.ITypingContext;
import edu.uci.ics.hyracks.algebricks.core.algebra.util.OperatorManipulationUtil;
import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalOperatorVisitor;

public class SubstituteVariableVisitor implements ILogicalOperatorVisitor<Void, Pair<LogicalVariable, LogicalVariable>> {

    private final boolean goThroughNts;
    private final ITypingContext ctx;

    public SubstituteVariableVisitor(boolean goThroughNts, ITypingContext ctx) {
        this.goThroughNts = goThroughNts;
        this.ctx = ctx;
    }

    @Override
    public Void visitAggregateOperator(AggregateOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        List<LogicalVariable> variables = op.getVariables();
        int n = variables.size();
        for (int i = 0; i < n; i++) {
            if (variables.get(i).equals(pair.first)) {
                variables.set(i, pair.second);
            } else {
                op.getExpressions().get(i).getValue().substituteVar(pair.first, pair.second);
            }
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitAssignOperator(AssignOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        List<LogicalVariable> variables = op.getVariables();
        int n = variables.size();
        for (int i = 0; i < n; i++) {
            if (variables.get(i).equals(pair.first)) {
                variables.set(i, pair.second);
            } else {
                op.getExpressions().get(i).getValue().substituteVar(pair.first, pair.second);
            }
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitDataScanOperator(DataSourceScanOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        List<LogicalVariable> variables = op.getVariables();
        for (int i = 0; i < variables.size(); i++) {
            if (variables.get(i) == pair.first) {
                variables.set(i, pair.second);
                return null;
            }
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitDistinctOperator(DistinctOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        for (Mutable<ILogicalExpression> eRef : op.getExpressions()) {
            eRef.getValue().substituteVar(pair.first, pair.second);
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitEmptyTupleSourceOperator(EmptyTupleSourceOperator op, Pair<LogicalVariable, LogicalVariable> pair) {
        // does not use any variable
        return null;
    }

    @Override
    public Void visitExchangeOperator(ExchangeOperator op, Pair<LogicalVariable, LogicalVariable> pair) {
        // does not use any variable
        return null;
    }

    @Override
    public Void visitGroupByOperator(GroupByOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        subst(pair.first, pair.second, op.getGroupByList());
        subst(pair.first, pair.second, op.getDecorList());
        for (ILogicalPlan p : op.getNestedPlans()) {
            for (Mutable<ILogicalOperator> r : p.getRoots()) {
                OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getValue(), pair.first,
                        pair.second, goThroughNts, ctx);
            }
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitInnerJoinOperator(InnerJoinOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        op.getCondition().getValue().substituteVar(pair.first, pair.second);
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitLeftOuterJoinOperator(LeftOuterJoinOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        op.getCondition().getValue().substituteVar(pair.first, pair.second);
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitLimitOperator(LimitOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        op.getMaxObjects().getValue().substituteVar(pair.first, pair.second);
        ILogicalExpression offset = op.getOffset().getValue();
        if (offset != null) {
            offset.substituteVar(pair.first, pair.second);
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitDieOperator(DieOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        op.getAfterObjects().getValue().substituteVar(pair.first, pair.second);
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitNestedTupleSourceOperator(NestedTupleSourceOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        return null;
    }

    @Override
    public Void visitOrderOperator(OrderOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        for (Pair<IOrder, Mutable<ILogicalExpression>> oe : op.getOrderExpressions()) {
            oe.second.getValue().substituteVar(pair.first, pair.second);
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitPartitioningSplitOperator(PartitioningSplitOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        for (Mutable<ILogicalExpression> e : op.getExpressions()) {
            e.getValue().substituteVar(pair.first, pair.second);
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitProjectOperator(ProjectOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        List<LogicalVariable> usedVariables = op.getVariables();
        int n = usedVariables.size();
        for (int i = 0; i < n; i++) {
            LogicalVariable v = usedVariables.get(i);
            if (v.equals(pair.first)) {
                usedVariables.set(i, pair.second);
            }
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitRunningAggregateOperator(RunningAggregateOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        List<LogicalVariable> variables = op.getVariables();
        int n = variables.size();
        for (int i = 0; i < n; i++) {
            if (variables.get(i).equals(pair.first)) {
                variables.set(i, pair.second);
            } else {
                op.getExpressions().get(i).getValue().substituteVar(pair.first, pair.second);
            }
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitScriptOperator(ScriptOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        substInArray(op.getInputVariables(), pair.first, pair.second);
        substInArray(op.getOutputVariables(), pair.first, pair.second);
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitSelectOperator(SelectOperator op, Pair<LogicalVariable, LogicalVariable> pair) {
        op.getCondition().getValue().substituteVar(pair.first, pair.second);
        return null;
    }

    @Override
    public Void visitSubplanOperator(SubplanOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        for (ILogicalPlan p : op.getNestedPlans()) {
            for (Mutable<ILogicalOperator> r : p.getRoots()) {
                OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getValue(), pair.first,
                        pair.second, goThroughNts, ctx);
            }
        }
        return null;
    }

    @Override
    public Void visitUnionOperator(UnionAllOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        List<Triple<LogicalVariable, LogicalVariable, LogicalVariable>> varMap = op.getVariableMappings();
        for (Triple<LogicalVariable, LogicalVariable, LogicalVariable> t : varMap) {
            if (t.first.equals(pair.first)) {
                t.first = pair.second;
            }
            if (t.second.equals(pair.first)) {
                t.second = pair.second;
            }
            if (t.third.equals(pair.first)) {
                t.third = pair.second;
            }
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitUnnestMapOperator(UnnestMapOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        List<LogicalVariable> variables = op.getVariables();
        for (int i = 0; i < variables.size(); i++) {
            if (variables.get(i) == pair.first) {
                variables.set(i, pair.second);
                return null;
            }
        }
        op.getExpressionRef().getValue().substituteVar(pair.first, pair.second);
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitUnnestOperator(UnnestOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        List<LogicalVariable> variables = op.getVariables();
        for (int i = 0; i < variables.size(); i++) {
            if (variables.get(i) == pair.first) {
                variables.set(i, pair.second);
                return null;
            }
        }
        op.getExpressionRef().getValue().substituteVar(pair.first, pair.second);
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitWriteOperator(WriteOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        for (Mutable<ILogicalExpression> e : op.getExpressions()) {
            e.getValue().substituteVar(pair.first, pair.second);
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitDistributeResultOperator(DistributeResultOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        for (Mutable<ILogicalExpression> e : op.getExpressions()) {
            e.getValue().substituteVar(pair.first, pair.second);
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitWriteResultOperator(WriteResultOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        op.getPayloadExpression().getValue().substituteVar(pair.first, pair.second);
        for (Mutable<ILogicalExpression> e : op.getKeyExpressions()) {
            e.getValue().substituteVar(pair.first, pair.second);
        }
        substVarTypes(op, pair);
        return null;
    }

    private void subst(LogicalVariable v1, LogicalVariable v2,
            List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> varExprPairList) {
        for (Pair<LogicalVariable, Mutable<ILogicalExpression>> ve : varExprPairList) {
            if (ve.first != null && ve.first.equals(v1)) {
                ve.first = v2;
                return;
            }
            ve.second.getValue().substituteVar(v1, v2);
        }
    }

    private void substInArray(ArrayList<LogicalVariable> varArray, LogicalVariable v1, LogicalVariable v2) {
        for (int i = 0; i < varArray.size(); i++) {
            LogicalVariable v = varArray.get(i);
            if (v == v1) {
                varArray.set(i, v2);
            }
        }
    }

    @Override
    public Void visitReplicateOperator(ReplicateOperator op, Pair<LogicalVariable, LogicalVariable> arg)
            throws AlgebricksException {
        op.substituteVar(arg.first, arg.second);
        return null;
    }

    @Override
    public Void visitInsertDeleteOperator(InsertDeleteOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        op.getPayloadExpression().getValue().substituteVar(pair.first, pair.second);
        for (Mutable<ILogicalExpression> e : op.getPrimaryKeyExpressions()) {
            e.getValue().substituteVar(pair.first, pair.second);
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitIndexInsertDeleteOperator(IndexInsertDeleteOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        for (Mutable<ILogicalExpression> e : op.getPrimaryKeyExpressions()) {
            e.getValue().substituteVar(pair.first, pair.second);
        }
        for (Mutable<ILogicalExpression> e : op.getSecondaryKeyExpressions()) {
            e.getValue().substituteVar(pair.first, pair.second);
        }
        substVarTypes(op, pair);
        return null;
    }

    @Override
    public Void visitSinkOperator(SinkOperator op, Pair<LogicalVariable, LogicalVariable> pair)
            throws AlgebricksException {
        return null;
    }

    private void substVarTypes(ILogicalOperator op, Pair<LogicalVariable, LogicalVariable> arg)
            throws AlgebricksException {
        if (ctx == null) {
            return;
        }
        IVariableTypeEnvironment env = ctx.getOutputTypeEnvironment(op);
        env.substituteProducedVariable(arg.first, arg.second);
    }

    @Override
    public Void visitExtensionOperator(ExtensionOperator op, Pair<LogicalVariable, LogicalVariable> arg)
            throws AlgebricksException {
        return null;
    }
}
