/*
 * Copyright 2018 The Bazel Authors. All rights reserved.
 *
 * 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 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 io.bazel.ruleskotlin.workers.compilers.jvm.utils;

import com.google.devtools.build.lib.view.proto.Deps;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RunWith(JUnit4.class)
public class JdepsParserTest {
    private static final String JDK8_FIXTURE =
            "alt.jar -> bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib-jdk7.jar\n" +
                    "alt.jar -> bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib.jar\n" +
                    "alt.jar -> bazel-bin/cloud/qa/integrationtests/pkg/extensions/postgres/postgres.jar\n" +
                    "alt.jar -> bazel-server-cloud/bazel-out/darwin-fastbuild/bin/cloud/qa/integrationtests/pkg/alt/alt.runfiles/__main__/external/org_postgresql_postgresql/jar/postgresql-42.1.1.jar\n" +
                    "alt.jar -> /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/rt.jar\n" +
                    "alt.jar -> bazel-bin/cloud/qa/integrationtests/pkg/utils/utils.jar\n" +
                    "   com.axsy.testing.alt (alt.jar)\n" +
                    "      -> com.axsy.testing.extensions.postgres               postgres.jar\n" +
                    "      -> com.axsy.testing.pkg.utils                         utils.jar\n" +
                    "      -> java.io                                            \n" +
                    "      -> java.lang                                          \n" +
                    "      -> java.sql                                           \n" +
                    "      -> javax.sql                                          \n" +
                    "      -> kotlin                                             kotlin-stdlib.jar\n" +
                    "      -> kotlin.jdk7                                        kotlin-stdlib-jdk7.jar\n" +
                    "      -> kotlin.jvm.internal                                kotlin-stdlib.jar\n" +
                    "      -> org.postgresql.ds                                  postgresql-42.1.1.jar\n" +
                    "   com.axsy.testing.alt.sub (alt.jar)\n" +
                    "      -> java.lang                                          \n" +
                    "      -> kotlin                                             kotlin-stdlib.jar\n";

    private static final String JDK9_FIXTURE =
            "alt.jar -> java.base\n" +
                    "alt.jar -> java.sql\n" +
                    "alt.jar -> bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib-jdk7.jar\n" +
                    "alt.jar -> bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib.jar\n" +
                    "alt.jar -> bazel-bin/cloud/qa/integrationtests/pkg/extensions/postgres/postgres.jar\n" +
                    "alt.jar -> bazel-server-cloud/bazel-out/darwin-fastbuild/bin/cloud/qa/integrationtests/pkg/alt/alt.runfiles/__main__/external/org_postgresql_postgresql/jar/postgresql-42.1.1.jar\n" +
                    "alt.jar -> bazel-bin/cloud/qa/integrationtests/pkg/utils/utils.jar\n" +
                    "   com.axsy.testing.alt                               -> com.axsy.testing.extensions.postgres               postgres.jar\n" +
                    "   com.axsy.testing.alt                               -> com.axsy.testing.pkg.utils                         utils.jar\n" +
                    "   com.axsy.testing.alt                               -> java.io                                            java.base\n" +
                    "   com.axsy.testing.alt                               -> java.lang                                          java.base\n" +
                    "   com.axsy.testing.alt                               -> java.sql                                           java.sql\n" +
                    "   com.axsy.testing.alt                               -> javax.sql                                          java.sql\n" +
                    "   com.axsy.testing.alt                               -> kotlin                                             kotlin-stdlib.jar\n" +
                    "   com.axsy.testing.alt                               -> kotlin.jdk7                                        kotlin-stdlib-jdk7.jar\n" +
                    "   com.axsy.testing.alt                               -> kotlin.jvm.internal                                kotlin-stdlib.jar\n" +
                    "   com.axsy.testing.alt                               -> org.postgresql.ds                                  postgresql-42.1.1.jar\n" +
                    "   com.axsy.testing.alt.sub                           -> java.lang                                          java.base\n" +
                    "   com.axsy.testing.alt.sub                           -> kotlin                                             kotlin-stdlib.jar\n";


    private static final List<String> CLASSPATH = Arrays.asList(
            "bazel-bin/cloud/qa/integrationtests/pkg/extensions/postgres/unused.jar",
            "bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib-jdk8.jar",
            "bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib-jdk7.jar",
            "bazel-server-cloud/external/com_github_jetbrains_kotlin/lib/kotlin-stdlib.jar",
            "bazel-bin/cloud/qa/integrationtests/pkg/extensions/postgres/postgres.jar",
            "bazel-server-cloud/bazel-out/darwin-fastbuild/bin/cloud/qa/integrationtests/pkg/alt/alt.runfiles/__main__/external/org_postgresql_postgresql/jar/postgresql-42.1.1.jar",
            "bazel-bin/cloud/qa/integrationtests/pkg/utils/utils.jar"
    );


    private static final String LABEL = "//cloud/qa/integrationtests/pkg/alt";
    private static final String CLASS_JAR = "bazel-bin/something/alt.jar";

    private static final Predicate<String> IS_KOTLIN_IMPLICIT = JdepsParser.pathSuffixMatchingPredicate(
            Paths.get("external", "com_github_jetbrains_kotlin", "lib"),
            "kotlin-stdlib.jar",
            "kotlin-stdlib-jdk7.jar",
            "kotlin-stdlib-jdk8.jar");

    @Test
    public void parseJDK8Format() throws IOException {
        testWithFixture(JDK8_FIXTURE);
    }

    @Test
    public void parseJDK9Format() throws IOException {
        testWithFixture(JDK9_FIXTURE);
    }

    private void testWithFixture(String fixture) throws IOException {
        Deps.Dependencies result = JdepsParser.parse(LABEL, CLASS_JAR, CLASSPATH.stream().collect(Collectors.joining(":")), Stream.of(fixture.split("\n")), IS_KOTLIN_IMPLICIT);
        Assert.assertEquals(LABEL, result.getRuleLabel());

        Assert.assertEquals(7, result.getDependencyCount());
        Assert.assertEquals(1, depKinds(result, Deps.Dependency.Kind.UNUSED).size());
        Assert.assertEquals(3, depKinds(result, Deps.Dependency.Kind.IMPLICIT).size());
        Assert.assertEquals(3, depKinds(result, Deps.Dependency.Kind.EXPLICIT).size());

        Assert.assertEquals(2, result.getContainedPackageCount());

        result.writeTo(System.out);
        System.out.flush();
    }

    private List<Deps.Dependency> depKinds(Deps.Dependencies result, Deps.Dependency.Kind kind) {
        return result.getDependencyList().stream().filter(x -> x.getKind() == kind).collect(Collectors.toList());
    }
}

