package io.vrap.rmf.raml.persistence;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import org.assertj.core.util.Lists;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;

@Ignore
@RunWith(DataProviderRunner.class)
public class RamlTck2Test implements ResourceFixtures {
    private class TckParseException extends Exception {
        public TckParseException(String message, Throwable cause) {
            super(message, cause);
        }
    }
    private final static URL tckURL = RamlTck2Test.class.getResource("/raml-tck-wip-2.0.0/tests");

    @Test
    @UseDataProvider("tckSemanticFiles")
    public void semantic(final File f, final Boolean valid, final String description) throws IOException, TckParseException {
        tckParse(f, valid, description);
    }

    @Test
    @UseDataProvider("tckSpecExampleFiles")
    public void specExamples(final File f, final Boolean valid, final String description) throws IOException, TckParseException {
        tckParse(f, valid, description);
    }

    @Test
    @UseDataProvider("tckSyntaxFiles")
    public void syntax(final File f, final Boolean valid, final String description) throws IOException, TckParseException {
        tckParse(f, valid, description);
    }

    public void tckParse(final File f, final Boolean valid, final String description) throws IOException, TckParseException {
        final Resource resource;
        final URI fileURI = URI.createURI(f.toURI().toString());
        try {
            resource = fromUri(fileURI);
        } catch (Exception e) {
            throw new TckParseException(fileURI.toString(), e);
        }
        try {
            if (valid) {
                assertThat(resource.getErrors()).describedAs(description).isEmpty();
            } else {
                assertThat(resource.getErrors()).describedAs(description).isNotEmpty();
            }
        } catch (AssertionError e) {
            throw new TckParseException(fileURI.toString(), e);
        }
    }

    @DataProvider
    public static List<List<Object>> tckSemanticFiles() throws IOException {
        return testFiles("semantic");
    }

    @DataProvider
    public static List<List<Object>> tckSpecExampleFiles() throws IOException {
        return testFiles("spec-examples");
    }

    @DataProvider
    public static List<List<Object>> tckSyntaxFiles() throws IOException {
        return testFiles("syntax");
    }

    @DataProvider
    public static List<List<Object>> testFiles(final String testSuite) throws IOException {
        final List<File> files = Files.walk(Paths.get(tckURL.getPath()))
                .filter(Files::isRegularFile)
                .filter(path -> path.toString().contains(testSuite))
                .filter(path -> path.toString().endsWith("test-config.json")).map(Path::toFile).collect(Collectors.toList());
        return files.stream().map(file -> {
            List<List<Object>> map = Lists.newArrayList();
            ObjectMapper mapper = new ObjectMapper();
            try {
                JsonNode json = mapper.readValue(file, JsonNode.class);
                JsonNode tests = json.get("tests");
                if (tests != null) {
                    tests.elements().forEachRemaining(jsonNode -> {
                        List<Object> a = Lists.newArrayList(
                                new File(file.getParentFile().getPath() + "/" + jsonNode.get("input").asText()),
                                jsonNode.get("valid").asBoolean(),
                                jsonNode.get("description").asText()
                        );
                        map.add(a);
                    });
                }
            } catch (Exception e) {

            }
            return map;
        }).flatMap(List::stream).collect(Collectors.toList());
    }
}

@@ -2227,34 +2227,16 @@
       %7D%0A
-        try %7B%0A    
         
@@ -2244,28 +2244,24 @@
 f (valid) %7B%0A
-    
             
@@ -2297,32 +2297,90 @@
 ()).describedAs(
+fileURI.toString().replace(tckURL.getPath(), %22%22) + %22: %22 + 
 description).isE
@@ -2395,20 +2395,16 @@
         
-    
 %7D else %7B
@@ -2404,20 +2404,16 @@
  else %7B%0A
-    
         
@@ -2465,147 +2465,90 @@
 dAs(
-description).isNotEmpty();%0A            %7D%0A        %7D catch (AssertionError e) %7B%0A            throw new TckParseException(fileURI.toString(), e
+fileURI.toString().replace(tckURL.getPath(), %22%22) + %22: %22 + description).isNotEmpty(
 );%0A 

remove unneeded exception wrapper