/*
 *  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.tinkerpop.gremlin.python.jsr223;

import org.apache.commons.configuration.ConfigurationConverter;
import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
import org.apache.tinkerpop.gremlin.process.traversal.Operator;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
import org.apache.tinkerpop.gremlin.process.traversal.TextP;
import org.apache.tinkerpop.gremlin.process.traversal.Translator;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy;
import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP;
import org.apache.tinkerpop.gremlin.process.traversal.util.OrP;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Element;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.structure.VertexProperty;
import org.apache.tinkerpop.gremlin.structure.util.StringFactory;
import org.apache.tinkerpop.gremlin.util.function.Lambda;
import org.apache.tinkerpop.gremlin.util.iterator.ArrayIterator;
import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @deprecated As of release 3.3.10, not replaced - see TINKERPOP-2317
 *
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
@Deprecated
public class PythonTranslator implements Translator.ScriptTranslator {

    private static final Set<String> STEP_NAMES = Stream.of(GraphTraversal.class.getMethods()).filter(method -> Traversal.class.isAssignableFrom(method.getReturnType())).map(Method::getName).collect(Collectors.toSet());
    private static final Set<String> NO_STATIC = Stream.of(T.values(), Operator.values())
            .flatMap(arg -> IteratorUtils.stream(new ArrayIterator<>(arg)))
            .map(arg -> ((Enum) arg).name())
            .collect(Collectors.toCollection(() -> new HashSet<>(Collections.singleton("not"))));

    private final String traversalSource;
    private final boolean importStatics;

    PythonTranslator(final String traversalSource, final boolean importStatics) {
        this.traversalSource = traversalSource;
        this.importStatics = importStatics;
    }

    public static PythonTranslator of(final String traversalSource, final boolean importStatics) {
        return new PythonTranslator(traversalSource, importStatics);
    }

    public static PythonTranslator of(final String traversalSource) {
        return new PythonTranslator(traversalSource, false);
    }

    @Override
    public String getTraversalSource() {
        return this.traversalSource;
    }

    @Override
    public String translate(final Bytecode bytecode) {
        return this.internalTranslate(this.traversalSource, bytecode);
    }

    @Override
    public String getTargetLanguage() {
        return "gremlin-python";
    }

    @Override
    public String toString() {
        return StringFactory.translatorString(this);
    }

    ///////

    private String internalTranslate(final String start, final Bytecode bytecode) {
        final StringBuilder traversalScript = new StringBuilder(start);
        for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
            final String methodName = instruction.getOperator();
            final Object[] arguments = instruction.getArguments();
            if (0 == arguments.length)
                traversalScript.append(".").append(resolveSymbol(methodName)).append("()");
            else if (methodName.equals("range") && 2 == arguments.length)
                if (((Number) arguments[0]).longValue() + 1 == ((Number) arguments[1]).longValue())
                    traversalScript.append("[").append(arguments[0]).append("]");
                else
                    traversalScript.append("[").append(arguments[0]).append(":").append(arguments[1]).append("]");
            else if (methodName.equals("limit") && 1 == arguments.length)
                traversalScript.append("[0:").append(arguments[0]).append("]");
            else if (methodName.equals("values") && 1 == arguments.length && traversalScript.length() > 3 && !STEP_NAMES.contains(arguments[0].toString()))
                traversalScript.append(".").append(arguments[0]);
            else {
                traversalScript.append(".");
                String temp = resolveSymbol(methodName) + "(";

                // jython has trouble with java varargs...wrapping in collection seems to solve the problem
                final boolean varargsBeware = instruction.getOperator().equals(TraversalSource.Symbols.withStrategies)
                            || instruction.getOperator().equals(TraversalSource.Symbols.withoutStrategies);
                if (varargsBeware) temp = temp + "[";

                for (final Object object : arguments) {
                    temp = temp + convertToString(object) + ",";
                }
                temp = temp.substring(0, temp.length() - 1);

                if (varargsBeware) temp = temp + "]";

                traversalScript.append(temp).append(")");
            }
            // clip off __.
            if (this.importStatics && traversalScript.substring(0, 3).startsWith("__.")
                    && !NO_STATIC.stream().filter(name -> traversalScript.substring(3).startsWith(resolveSymbol(name))).findAny().isPresent()) {
                traversalScript.delete(0, 3);
            }
        }
        return traversalScript.toString();
    }

    protected String convertToString(final Object object) {
        if (object instanceof Bytecode.Binding)
            return ((Bytecode.Binding) object).variable();
        else if (object instanceof Bytecode)
            return this.internalTranslate("__", (Bytecode) object);
        else if (object instanceof Traversal)
            return convertToString(((Traversal) object).asAdmin().getBytecode());
        else if (object instanceof String)
            return ((String) object).contains("\"") ? "\"\"\"" + object + "\"\"\"" : "\"" + object + "\"";
        else if (object instanceof Set) {
            final Set<String> set = new LinkedHashSet<>(((Set) object).size());
            for (final Object item : (Set) object) {
                set.add(convertToString(item));
            }
            return "set(" + set.toString() + ")";
        } else if (object instanceof List) {
            final List<String> list = new ArrayList<>(((List) object).size());
            for (final Object item : (List) object) {
                list.add(convertToString(item));
            }
            return list.toString();
        } else if (object instanceof Map) {
            final StringBuilder map = new StringBuilder("{");
            for (final Map.Entry<?, ?> entry : ((Map<?, ?>) object).entrySet()) {
                map.append(convertToString(entry.getKey())).
                        append(":").
                        append(convertToString(entry.getValue())).
                        append(",");
            }
            return map.length() > 1 ? map.substring(0, map.length() - 1) + "}" : map.append("}").toString();
        } else if (object instanceof Long)
            return object + "L";
        else if (object instanceof TraversalStrategyProxy) {
            return resolveTraversalStrategyProxy((TraversalStrategyProxy) object);
        } else if (object instanceof TraversalStrategy) {
            return convertToString(new TraversalStrategyProxy((TraversalStrategy) object));
        } else if (object instanceof Boolean)
            return object.equals(Boolean.TRUE) ? "True" : "False";
        else if (object instanceof Class)
            return ((Class) object).getCanonicalName();
        else if (object instanceof VertexProperty.Cardinality)
            return "Cardinality." + resolveSymbol(object.toString());
        else if (object instanceof SackFunctions.Barrier)
            return "Barrier." + resolveSymbol(object.toString());
        else if (object instanceof TraversalOptionParent.Pick)
            return "Pick." + resolveSymbol(object.toString());
        else if (object instanceof Enum)
            return convertStatic(((Enum) object).getDeclaringClass().getSimpleName() + ".") + resolveSymbol(object.toString());
        else if (object instanceof P)
            return convertPToString((P) object, new StringBuilder()).toString();
        else if (object instanceof Element) {
            if (object instanceof Vertex) {
                final Vertex vertex = (Vertex) object;
                return "Vertex(" + convertToString(vertex.id()) + "," + convertToString(vertex.label()) + ")";
            } else if (object instanceof Edge) {
                final Edge edge = (Edge) object;
                return "Edge(" + convertToString(edge.id()) + "," +
                        convertToString(edge.outVertex()) + "," +
                        convertToString(edge.label()) + "," +
                        convertToString(edge.inVertex()) + ")";
            } else {
                final VertexProperty vertexProperty = (VertexProperty) object;
                return "VertexProperty(" + convertToString(vertexProperty.id()) + "," +
                        convertToString(vertexProperty.label()) + "," +
                        convertToString(vertexProperty.value()) + ")";
            }
        } else if (object instanceof Lambda)
            return convertLambdaToString((Lambda) object);
        else
            return null == object ? "None" : object.toString();
    }

    private String convertStatic(final String name) {
        return this.importStatics ? "" : name;
    }

    private StringBuilder convertPToString(final P p, final StringBuilder current) {
        if (p instanceof TextP) return convertTextPToString((TextP) p, current);
        if (p instanceof ConnectiveP) {
            final List<P<?>> list = ((ConnectiveP) p).getPredicates();
            for (int i = 0; i < list.size(); i++) {
                convertPToString(list.get(i), current);
                if (i < list.size() - 1)
                    current.append(p instanceof OrP ? ".or_(" : ".and_(");
            }
            current.append(")");
        } else
            current.append(convertStatic("P.")).append(p.getBiPredicate().toString()).append("(").append(convertToString(p.getValue())).append(")");
        return current;
    }

    private StringBuilder convertTextPToString(final TextP p, final StringBuilder current) {
        current.append(convertStatic("TextP.")).append(p.getBiPredicate().toString()).append("(").append(convertToString(p.getValue())).append(")");
        return current;
    }

    protected String convertLambdaToString(final Lambda lambda) {
        final String lambdaString = lambda.getLambdaScript().trim();
        return lambdaString.startsWith("lambda") ? lambdaString : "lambda " + lambdaString;
    }

    protected String resolveSymbol(final String methodName) {
        return SymbolHelper.toPython(methodName);
    }

    protected String resolveTraversalStrategyProxy(final TraversalStrategyProxy proxy) {
        if (proxy.getConfiguration().isEmpty())
            return "TraversalStrategy(\"" + proxy.getStrategyClass().getSimpleName() + "\")";
        else
            return "TraversalStrategy(\"" + proxy.getStrategyClass().getSimpleName() + "\"," + convertToString(ConfigurationConverter.getMap(proxy.getConfiguration())) + ")";
    }
}
