/*
 * 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.language.grammar;

import org.apache.tinkerpop.gremlin.language.corpus.DocumentationReader;
import org.apache.tinkerpop.gremlin.language.corpus.FeatureReader;
import org.javatuples.Pair;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.hamcrest.Matchers.is;
import static org.junit.Assume.assumeThat;

/**
 * Builds a corpus of Gremlin statements from Recipes, "The Traversal" in Reference Documentation and the Gherkin
 * test suite and passes them all through the grammar parser.
 */
@RunWith(Parameterized.class)
public class ReferenceGrammarTest extends AbstractGrammarTest {
    private static final String featureDir = Paths.get("..", "gremlin-test", "src", "main", "resources", "org", "apache", "tinkerpop", "gremlin", "test", "features").toString();
    private static final String docsDir = Paths.get("..", "docs", "src").toString();

    private static final Pattern edgePattern = Pattern.compile(".*e\\d.*");

    private static final List<Pair<Pattern, BiFunction<String,String,String>>> stringMatcherConverters = new ArrayList<Pair<Pattern, BiFunction<String,String,String>>>() {{
        add(Pair.with(Pattern.compile("m\\[(.*)\\]"), (k,v) -> {
            // can't handled embedded maps because of the string replace below on the curly braces
            final String[] items = v.replace("{", "").replace("}", "").split(",");
            final String listItems = Stream.of(items).map(String::trim).map(x -> {
                final String[] pair = x.split(":");
                final String convertedKey = String.format("%s", pair[0]);
                final String convertedValue = String.format("%s", pair[1]);
                return String.format("%s:%s", convertedKey, convertedValue);
            }).collect(Collectors.joining(","));
            return String.format("[%s]", listItems);
        }));
        add(Pair.with(Pattern.compile("l\\[\\]"), (k,v) -> "[]"));
        add(Pair.with(Pattern.compile("l\\[(.*)\\]"), (k,v) -> {
            final String[] items = v.split(",");
            final String listItems = Stream.of(items).map(String::trim).map(x -> String.format("\"%s\"", x)).collect(Collectors.joining(","));
            return String.format("[%s]", listItems);
        }));
        add(Pair.with(Pattern.compile("v\\[(.+)\\]"), (k,v) -> "\"1\""));
        add(Pair.with(Pattern.compile("v(\\d)"), (k,v) -> String.format("new Vertex(%s, \"vertex\")", v)));
        add(Pair.with(Pattern.compile("e\\[(.+)\\]"), (k,v) -> "\"1\""));
        add(Pair.with(Pattern.compile("d\\[(.*)\\]\\.?.*"), (k,v) -> v));
        add(Pair.with(Pattern.compile("m\\[(.*)\\]"), (k,v) -> v.replace('{','[').replace('}', ']')));
        add(Pair.with(Pattern.compile("t\\[(.*)\\]"), (k,v) -> String.format("T.%s", v)));
        add(Pair.with(Pattern.compile("D\\[(.*)\\]"), (k,v) -> String.format("Direction.%s", v)));

        // the grammar doesn't support all the Gremlin we have in the gherkin set, so try to coerce it into
        // something that can be parsed so that we get maximum exercise over the parser itself.
        add(Pair.with(Pattern.compile("c\\[(.*)\\]"), (k,v) -> k.equals("c1") || k.equals("c2") ? "Order.desc" : "__.identity()"));  // closure -> Comparator || Traversal
        add(Pair.with(Pattern.compile("s\\[\\]"), (k,v) -> "[]"));  // set -> list
        add(Pair.with(Pattern.compile("s\\[(.*)\\]"), (k,v) -> "[]"));  // set -> list
        add(Pair.with(Pattern.compile("(null)"), (k,v) -> "null"));
        add(Pair.with(Pattern.compile("(true)"), (k,v) -> "true"));
        add(Pair.with(Pattern.compile("(false)"), (k,v) -> "false"));

    }};

    @Parameterized.Parameters(name = "{0}")
    public static Iterable<String> queries() throws IOException {
        final Set<String> gremlins = new LinkedHashSet<>(DocumentationReader.parse(docsDir));
        gremlins.addAll(FeatureReader.parseGrouped(featureDir, stringMatcherConverters).values().stream().flatMap(Collection::stream).collect(Collectors.toList()));
        return gremlins;
    }

    @Parameterized.Parameter
    public String query;

    @Test
    public void test_parse() {
        // can't handle maps with complex embedded types at the moment - basically one Gremlin statement at this point
        assumeThat("Complex embedded types are not supported", query.contains("l[\"666\"]"), is(false));
        assumeThat("Lambdas are not supported", query.contains("Lambda.function("), is(false));
        // start of a closure
        assumeThat("Lambdas are not supported", query.contains("{"), is(false));
        assumeThat("withComputer() step is not supported", query.startsWith("g.withComputer("), is(false));
        assumeThat("Edge instances are not supported", edgePattern.matcher(query).matches(), is(false));
        assumeThat("fill() terminator is not supported", query.contains("fill("), is(false));
        assumeThat("withoutStrategies() is not supported", query.contains("withoutStrategies("), is(false));
        assumeThat("program() is not supported", query.contains("program("), is(false));
        assumeThat("Casts are not supported", query.contains("(Map)"), is(false));

        parse(query);
    }
}
