/*
 * 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.vxquery.compiler.algebricks.prettyprint;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.commons.lang3.mutable.Mutable;
import org.apache.vxquery.compiler.algebricks.VXQueryConstantValue;
import org.apache.vxquery.context.StaticContext;
import org.apache.vxquery.datamodel.accessors.TaggedValuePointable;
import org.apache.vxquery.datamodel.values.ValueTag;
import org.apache.vxquery.functions.BuiltinOperators;
import org.apache.vxquery.serializer.XMLSerializer;
import org.apache.vxquery.types.SequenceType;

import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IAlgebricksConstantValue;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.StatefulFunctionCallExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.UnnestingFunctionCallExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import edu.uci.ics.hyracks.algebricks.core.algebra.visitors.ILogicalExpressionVisitor;
import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;

public class VXQueryLogicalExpressionPrettyPrintVisitor implements ILogicalExpressionVisitor<String, Integer> {

    StaticContext ctx;
    IntegerPointable ip;
    TaggedValuePointable tvp;
    XMLSerializer serializer;
    ByteArrayOutputStream os;
    PrintStream ps;

    public VXQueryLogicalExpressionPrettyPrintVisitor(StaticContext ctx) {
        this.ctx = ctx;
        this.ip = (IntegerPointable) IntegerPointable.FACTORY.createPointable();
        this.tvp = (TaggedValuePointable) TaggedValuePointable.FACTORY.createPointable();
        this.serializer = new XMLSerializer();
        this.os = new ByteArrayOutputStream();
        this.ps = new PrintStream(os);
    }

    @Override
    public String visitConstantExpression(ConstantExpression expr, Integer indent) throws AlgebricksException {
        IAlgebricksConstantValue value = expr.getValue();
        if (value instanceof VXQueryConstantValue) {
            VXQueryConstantValue vxqValue = (VXQueryConstantValue) value;
            tvp.set(vxqValue.getValue(), 0, vxqValue.getValue().length);
            serializer.printTaggedValuePointable(ps, tvp);
            try {
                return vxqValue.getType() + ": " + os.toString("UTF8");
            } catch (UnsupportedEncodingException e) {
                // print stack trace and return the default
                e.printStackTrace();
            } finally {
                ps.flush();
                os.reset();
            }
        }
        return value.toString();
    }

    @Override
    public String visitVariableReferenceExpression(VariableReferenceExpression expr, Integer indent)
            throws AlgebricksException {
        return expr.toString();
    }

    @Override
    public String visitAggregateFunctionCallExpression(AggregateFunctionCallExpression expr, Integer indent)
            throws AlgebricksException {
        return appendFunction(new StringBuilder(), expr, indent).toString();
    }

    @Override
    public String visitScalarFunctionCallExpression(ScalarFunctionCallExpression expr, Integer indent)
            throws AlgebricksException {
        assert expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL;

        StringBuilder sb = new StringBuilder();

        FunctionIdentifier fi = expr.getFunctionIdentifier();
        if (identifiesTypeOperator(fi)) {
            final ILogicalExpression typeEx = expr.getArguments().get(1).getValue();
            assert typeEx.getExpressionTag() == LogicalExpressionTag.CONSTANT;
            SequenceType type = getSequenceType((ConstantExpression) typeEx);
            sb.append(fi + " <" + type + ">, Args:");
            appendArgument(sb, expr.getArguments().get(0), indent + 2);
        } else {
            appendFunction(sb, expr, indent);
        }
        return sb.toString();
    }

    @Override
    public String visitStatefulFunctionCallExpression(StatefulFunctionCallExpression expr, Integer indent)
            throws AlgebricksException {
        return appendFunction(new StringBuilder(), expr, indent).toString();
    }

    @Override
    public String visitUnnestingFunctionCallExpression(UnnestingFunctionCallExpression expr, Integer indent)
            throws AlgebricksException {
        return appendFunction(new StringBuilder(), expr, indent).toString();
    }

    protected boolean identifiesTypeOperator(FunctionIdentifier fi) {
        return BuiltinOperators.PROMOTE.getFunctionIdentifier().equals(fi)
                || BuiltinOperators.TREAT.getFunctionIdentifier().equals(fi)
                || BuiltinOperators.CAST.getFunctionIdentifier().equals(fi)
                || BuiltinOperators.CASTABLE.getFunctionIdentifier().equals(fi)
                || BuiltinOperators.INSTANCE_OF.getFunctionIdentifier().equals(fi);
    }

    protected StringBuilder appendFunction(StringBuilder sb, AbstractFunctionCallExpression expr, Integer indent)
            throws AlgebricksException {
        sb.append("function-call: " + expr.getFunctionIdentifier() + ", Args:");
        appendArguments(sb, expr.getArguments(), indent + 2);
        return sb;
    }

    protected StringBuilder appendArguments(StringBuilder sb, List<Mutable<ILogicalExpression>> args, Integer indent)
            throws AlgebricksException {
        sb.append("[\n");
        for (Mutable<ILogicalExpression> arg : args) {
            addIndent(sb, indent + 2).append(arg.getValue().accept(this, indent + 2)).append("\n");
        }
        return addIndent(sb, indent).append("]");
    }

    protected StringBuilder appendArgument(StringBuilder sb, Mutable<ILogicalExpression> arg, Integer indent)
            throws AlgebricksException {
        sb.append("[\n");
        addIndent(sb, indent + 2).append(arg.getValue().accept(this, indent + 2)).append("\n");
        return addIndent(sb, indent).append("]");
    }

    protected SequenceType getSequenceType(final ConstantExpression cTypeEx) {
        final VXQueryConstantValue typeCodeVal = (VXQueryConstantValue) cTypeEx.getValue();
        tvp.set(typeCodeVal.getValue(), 0, typeCodeVal.getValue().length);
        assert tvp.getTag() == ValueTag.XS_INT_TAG;
        tvp.getValue(ip);
        int typeCode = ip.getInteger();
        SequenceType type = ctx.lookupSequenceType(typeCode);
        return type;
    }

    protected static final StringBuilder addIndent(StringBuilder buffer, int level) {
        for (int i = 0; i < level; ++i) {
            buffer.append(' ');
        }
        return buffer;
    }

}
