/*
 * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 8142968 8166568 8166286 8170618 8168149 8240910 8276764 8276766 8353267
 * @summary Basic test for jmod
 * @library /test/lib
 * @modules jdk.compiler
 *          jdk.jlink
 *          java.base/jdk.internal.module
 * @build jdk.test.lib.compiler.CompilerUtils
 *        jdk.test.lib.util.FileUtils
 *        jdk.test.lib.Platform
 * @run testng/othervm -Djava.io.tmpdir=. JmodTest
 */

import java.io.*;
import java.lang.module.ModuleDescriptor;
import java.lang.reflect.Method;
import java.nio.file.*;
import java.util.*;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.spi.ToolProvider;
import java.util.stream.Stream;
import jdk.test.lib.compiler.CompilerUtils;
import jdk.test.lib.util.FileUtils;
import jdk.test.lib.util.ModuleInfoWriter;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import static java.io.File.pathSeparator;
import static java.lang.module.ModuleDescriptor.Version;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toSet;
import static org.testng.Assert.*;

public class JmodTest {

    static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
        .orElseThrow(() ->
            new RuntimeException("jmod tool not found")
        );
    static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
        .orElseThrow(() ->
            new RuntimeException("jar tool not found")
        );

    static final String TEST_SRC = System.getProperty("test.src", ".");
    static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
    static final Path EXPLODED_DIR = Paths.get("build");
    static final Path MODS_DIR = Paths.get("jmods");

    static final String CLASSES_PREFIX = "classes/";
    static final String CMDS_PREFIX = "bin/";
    static final String LIBS_PREFIX = "lib/";
    static final String CONFIGS_PREFIX = "conf/";

    @BeforeTest
    public void buildExplodedModules() throws IOException {
        if (Files.exists(EXPLODED_DIR))
            FileUtils.deleteFileTreeWithRetry(EXPLODED_DIR);

        for (String name : new String[] { "foo"/*, "bar", "baz"*/ } ) {
            Path dir = EXPLODED_DIR.resolve(name);
            assertTrue(compileModule(name, dir.resolve("classes")));
            copyResource(SRC_DIR.resolve("foo"),
                         dir.resolve("classes"),
                         "jdk/test/foo/resources/foo.properties");
            createCmds(dir.resolve("bin"));
            createLibs(dir.resolve("lib"));
            createConfigs(dir.resolve("conf"));
        }

        if (Files.exists(MODS_DIR))
            FileUtils.deleteFileTreeWithRetry(MODS_DIR);
        Files.createDirectories(MODS_DIR);
    }

    // JDK-8166286 - jmod fails on symlink to directory
    @Test
    public void testDirSymlinks() throws IOException {
        Path apaDir = EXPLODED_DIR.resolve("apa");
        Path classesDir = EXPLODED_DIR.resolve("apa").resolve("classes");
        assertTrue(compileModule("apa", classesDir));
        Path libDir = apaDir.resolve("lib");
        createFiles(libDir, List.of("foo/bar/libfoo.so"));
        try {
            Path link = Files.createSymbolicLink(
                libDir.resolve("baz"), libDir.resolve("foo").toAbsolutePath());
            assertTrue(Files.exists(link));
        } catch (IOException|UnsupportedOperationException uoe) {
            // OS does not support symlinks. Nothing to test!
            System.out.println("Creating symlink failed. Test passes vacuously.");
            uoe.printStackTrace();
            return;
        }

        Path jmod = MODS_DIR.resolve("apa.jmod");
        jmod("create",
             "--libs=" + libDir.toString(),
             "--class-path", classesDir.toString(),
             jmod.toString())
            .assertSuccess();
        Files.delete(jmod);
    }

    // JDK-8267583 - jmod fails on symlink to class file
    @Test
    public void testFileSymlinks() throws IOException {
        Path apaDir = EXPLODED_DIR.resolve("apa");
        Path classesDir = EXPLODED_DIR.resolve("apa").resolve("classes");
        assertTrue(compileModule("apa", classesDir));

        Files.move(classesDir.resolve("module-info.class"),
            classesDir.resolve("module-info.class1"));
        Files.move(classesDir.resolve(Paths.get("jdk", "test", "apa", "Apa.class")),
            classesDir.resolve("Apa.class1"));
        try {
            Path link = Files.createSymbolicLink(
                classesDir.resolve("module-info.class"),
                classesDir.resolve("module-info.class1").toAbsolutePath());
            assertTrue(Files.exists(link));
            link = Files.createSymbolicLink(
                classesDir.resolve(Paths.get("jdk", "test", "apa", "Apa.class")),
                classesDir.resolve("Apa.class1").toAbsolutePath());
            assertTrue(Files.exists(link));
        } catch (IOException|UnsupportedOperationException uoe) {
            // OS does not support symlinks. Nothing to test!
            System.out.println("Creating symlinks failed. Test passes vacuously.");
            uoe.printStackTrace();
            return;
        }

        Path jmod = MODS_DIR.resolve("apa.jmod");
        jmod("create",
             "--class-path", classesDir.toString(),
             jmod.toString())
            .assertSuccess();
        Files.delete(jmod);
    }

    // JDK-8170618 - jmod should validate if any exported or open package is missing
    @Test
    public void testMissingPackages() throws IOException {
        Path apaDir = EXPLODED_DIR.resolve("apa");
        Path classesDir = EXPLODED_DIR.resolve("apa").resolve("classes");
        if (Files.exists(classesDir))
            FileUtils.deleteFileTreeWithRetry(classesDir);
        assertTrue(compileModule("apa", classesDir));
        FileUtils.deleteFileTreeWithRetry(classesDir.resolve("jdk"));
        Path jmod = MODS_DIR.resolve("apa.jmod");
        jmod("create",
             "--class-path", classesDir.toString(),
             jmod.toString())
            .assertFailure()
            .resultChecker(r -> {
                assertContains(r.output, "Packages that are exported or open in apa are not present: [jdk.test.apa]");
            });
        if (Files.exists(classesDir))
            FileUtils.deleteFileTreeWithRetry(classesDir);
    }

    @Test
    public void testList() throws IOException {
        String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
        Path jmod = MODS_DIR.resolve("foo.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        jmod("create",
             "--class-path", cp,
             jmod.toString())
            .assertSuccess();

        jmod("list",
             jmod.toString())
            .assertSuccess()
            .resultChecker(r -> {
                // asserts dependent on the exact contents of foo
                assertContains(r.output, CLASSES_PREFIX + "module-info.class");
                assertContains(r.output, CLASSES_PREFIX + "jdk/test/foo/Foo.class");
                assertContains(r.output, CLASSES_PREFIX + "jdk/test/foo/internal/Message.class");
                assertContains(r.output, CLASSES_PREFIX + "jdk/test/foo/resources/foo.properties");

                // JDK-8276764: Ensure the order is sorted for reproducible jmod content
                // module-info, followed by <sorted classes>
                int mod_info_i = r.output.indexOf(CLASSES_PREFIX + "module-info.class");
                int foo_cls_i  = r.output.indexOf(CLASSES_PREFIX + "jdk/test/foo/Foo.class");
                int msg_i      = r.output.indexOf(CLASSES_PREFIX + "jdk/test/foo/internal/Message.class");
                int res_i      = r.output.indexOf(CLASSES_PREFIX + "jdk/test/foo/resources/foo.properties");
                System.out.println("jmod classes sort order check:\n"+r.output);
                assertTrue(mod_info_i < foo_cls_i);
                assertTrue(foo_cls_i < msg_i);
                assertTrue(msg_i < res_i);
            });
    }

    @Test
    public void testSourceDateReproducible() throws IOException {
        String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
        Path jmod1 = MODS_DIR.resolve("foo1.jmod");
        Path jmod2 = MODS_DIR.resolve("foo2.jmod");
        Path jmod3 = MODS_DIR.resolve("foo3.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod1);
        FileUtils.deleteFileIfExistsWithRetry(jmod2);
        FileUtils.deleteFileIfExistsWithRetry(jmod3);

        // Use source date of 15/03/2022
        String sourceDate = "2022-03-15T00:00:00+00:00";

        jmod("create",
             "--class-path", cp,
             "--date", sourceDate,
             jmod1.toString())
            .assertSuccess();

        try {
            // Sleep 5 seconds to ensure zip timestamps might be different if they could be
            Thread.sleep(5000);
        } catch(InterruptedException ex) {}

        jmod("create",
             "--class-path", cp,
             "--date", sourceDate,
             jmod2.toString())
            .assertSuccess();

        // Compare file byte content to see if they are identical
        assertSameContent(jmod1, jmod2);

        // Use a date before 1980 and assert failure error
        sourceDate = "1976-03-15T00:00:00+00:00";

        jmod("create",
             "--class-path", cp,
             "--date", sourceDate,
             jmod3.toString())
            .assertFailure()
            .resultChecker(r -> {
                assertContains(r.output, "is out of the valid range");
            });

        // Use a date after 2099 and assert failure error
        sourceDate = "2100-03-15T00:00:00+00:00";

        jmod("create",
             "--class-path", cp,
             "--date", sourceDate,
             jmod3.toString())
            .assertFailure()
            .resultChecker(r -> {
                assertContains(r.output, "is out of the valid range");
            });
    }

    @Test
    public void testExtractCWD() throws IOException {
        Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
        jmod("create",
             "--class-path", cp.toString(),
             MODS_DIR.resolve("fooExtractCWD.jmod").toString())
            .assertSuccess();

        jmod("extract",
             MODS_DIR.resolve("fooExtractCWD.jmod").toString())
            .assertSuccess()
            .resultChecker(r -> {
                // module-info should exist, but jmod will have added its Packages attr.
                assertTrue(Files.exists(Paths.get("classes/module-info.class")));
                assertSameContent(cp.resolve("jdk/test/foo/Foo.class"),
                                  Paths.get("classes/jdk/test/foo/Foo.class"));
                assertSameContent(cp.resolve("jdk/test/foo/internal/Message.class"),
                                  Paths.get("classes/jdk/test/foo/internal/Message.class"));
                assertSameContent(cp.resolve("jdk/test/foo/resources/foo.properties"),
                                  Paths.get("classes/jdk/test/foo/resources/foo.properties"));
            });
    }

    @Test
    public void testExtractDir() throws IOException {
        if (Files.exists(Paths.get("extractTestDir")))
            FileUtils.deleteFileTreeWithRetry(Paths.get("extractTestDir"));
        Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
        Path bp = EXPLODED_DIR.resolve("foo").resolve("bin");
        Path lp = EXPLODED_DIR.resolve("foo").resolve("lib");
        Path cf = EXPLODED_DIR.resolve("foo").resolve("conf");

        jmod("create",
             "--conf", cf.toString(),
             "--cmds", bp.toString(),
             "--libs", lp.toString(),
             "--class-path", cp.toString(),
             MODS_DIR.resolve("fooExtractDir.jmod").toString())
            .assertSuccess();

        jmod("extract",
             "--dir", "extractTestDir",
             MODS_DIR.resolve("fooExtractDir.jmod").toString())
            .assertSuccess();

        jmod("extract",
             "--dir", "extractTestDir",
             MODS_DIR.resolve("fooExtractDir.jmod").toString())
            .assertSuccess()
            .resultChecker(r -> {
                // check a sample of the extracted files
                Path p = Paths.get("extractTestDir");
                assertTrue(Files.exists(p.resolve("classes/module-info.class")));
                assertSameContent(cp.resolve("jdk/test/foo/Foo.class"),
                                  p.resolve("classes/jdk/test/foo/Foo.class"));
                assertSameContent(bp.resolve("first"),
                                  p.resolve(CMDS_PREFIX).resolve("first"));
                assertSameContent(lp.resolve("first.so"),
                                  p.resolve(LIBS_PREFIX).resolve("second.so"));
                assertSameContent(cf.resolve("second.cfg"),
                                  p.resolve(CONFIGS_PREFIX).resolve("second.cfg"));
            });
    }

    @Test
    public void testMainClass() throws IOException {
        Path jmod = MODS_DIR.resolve("fooMainClass.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();

        jmod("create",
             "--class-path", cp,
             "--main-class", "jdk.test.foo.Foo",
             jmod.toString())
            .assertSuccess()
            .resultChecker(r -> {
                Optional<String> omc = getModuleDescriptor(jmod).mainClass();
                assertTrue(omc.isPresent());
                assertEquals(omc.get(), "jdk.test.foo.Foo");
            });
    }

    @Test
    public void testModuleVersion() throws IOException {
        Path jmod = MODS_DIR.resolve("fooVersion.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();

        jmod("create",
             "--class-path", cp,
             "--module-version", "5.4.3",
             jmod.toString())
            .assertSuccess()
            .resultChecker(r -> {
                Optional<Version> ov = getModuleDescriptor(jmod).version();
                assertTrue(ov.isPresent());
                assertEquals(ov.get().toString(), "5.4.3");
            });
    }

    @Test
    public void testConfig() throws IOException {
        Path jmod = MODS_DIR.resolve("fooConfig.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
        Path cf = EXPLODED_DIR.resolve("foo").resolve("conf");

        jmod("create",
             "--class-path", cp.toString(),
             "--config", cf.toString(),
             jmod.toString())
            .assertSuccess()
            .resultChecker(r -> {
                try (Stream<String> s1 = findFiles(cf).map(p -> CONFIGS_PREFIX + p);
                     Stream<String> s2 = findFiles(cp).map(p -> CLASSES_PREFIX + p)) {
                    Set<String> expectedFilenames = Stream.concat(s1, s2)
                                                          .collect(toSet());
                    assertJmodContent(jmod, expectedFilenames);
                }
            });
    }

    @Test
    public void testCmds() throws IOException {
        Path jmod = MODS_DIR.resolve("fooCmds.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
        Path bp = EXPLODED_DIR.resolve("foo").resolve("bin");

        jmod("create",
             "--cmds", bp.toString(),
             "--class-path", cp.toString(),
             jmod.toString())
            .assertSuccess()
            .resultChecker(r -> {
                try (Stream<String> s1 = findFiles(bp).map(p -> CMDS_PREFIX + p);
                     Stream<String> s2 = findFiles(cp).map(p -> CLASSES_PREFIX + p)) {
                    Set<String> expectedFilenames = Stream.concat(s1,s2)
                                                          .collect(toSet());
                    assertJmodContent(jmod, expectedFilenames);
                }
            });
    }

    @Test
    public void testLibs() throws IOException {
        Path jmod = MODS_DIR.resolve("fooLibs.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
        Path lp = EXPLODED_DIR.resolve("foo").resolve("lib");

        jmod("create",
             "--libs=" + lp.toString(),
             "--class-path", cp.toString(),
             jmod.toString())
            .assertSuccess()
            .resultChecker(r -> {
                try (Stream<String> s1 = findFiles(lp).map(p -> LIBS_PREFIX + p);
                     Stream<String> s2 = findFiles(cp).map(p -> CLASSES_PREFIX + p)) {
                    Set<String> expectedFilenames = Stream.concat(s1,s2)
                                                          .collect(toSet());
                    assertJmodContent(jmod, expectedFilenames);
                }
            });
    }

    @Test
    public void testAll() throws IOException {
        Path jmod = MODS_DIR.resolve("fooAll.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
        Path bp = EXPLODED_DIR.resolve("foo").resolve("bin");
        Path lp = EXPLODED_DIR.resolve("foo").resolve("lib");
        Path cf = EXPLODED_DIR.resolve("foo").resolve("conf");

        jmod("create",
             "--conf", cf.toString(),
             "--cmds=" + bp.toString(),
             "--libs=" + lp.toString(),
             "--class-path", cp.toString(),
             jmod.toString())
            .assertSuccess()
            .resultChecker(r -> {
                try (Stream<String> s1 = findFiles(lp).map(p -> LIBS_PREFIX + p);
                     Stream<String> s2 = findFiles(cp).map(p -> CLASSES_PREFIX + p);
                     Stream<String> s3 = findFiles(bp).map(p -> CMDS_PREFIX + p);
                     Stream<String> s4 = findFiles(cf).map(p -> CONFIGS_PREFIX + p)) {
                    Set<String> expectedFilenames = Stream.concat(Stream.concat(s1,s2),
                                                                  Stream.concat(s3, s4))
                                                          .collect(toSet());
                    assertJmodContent(jmod, expectedFilenames);
                }
            });
    }

    @Test
    public void testExcludes() throws IOException {
        Path jmod = MODS_DIR.resolve("fooLibs.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
        Path lp = EXPLODED_DIR.resolve("foo").resolve("lib");

        jmod("create",
             "--libs=" + lp.toString(),
             "--class-path", cp.toString(),
             "--exclude", "**internal**",
             "--exclude", "first.so",
             jmod.toString())
             .assertSuccess()
             .resultChecker(r -> {
                 Set<String> expectedFilenames = new HashSet<>();
                 expectedFilenames.add(CLASSES_PREFIX + "module-info.class");
                 expectedFilenames.add(CLASSES_PREFIX + "jdk/test/foo/Foo.class");
                 expectedFilenames.add(CLASSES_PREFIX + "jdk/test/foo/resources/foo.properties");
                 expectedFilenames.add(LIBS_PREFIX + "second.so");
                 expectedFilenames.add(LIBS_PREFIX + "third/third.so");
                 assertJmodContent(jmod, expectedFilenames);

                 Set<String> unexpectedFilenames = new HashSet<>();
                 unexpectedFilenames.add(CLASSES_PREFIX + "jdk/test/foo/internal/Message.class");
                 unexpectedFilenames.add(LIBS_PREFIX + "first.so");
                 assertJmodDoesNotContain(jmod, unexpectedFilenames);
             });
    }

    @Test
    public void describe() throws IOException {
        String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
        jmod("create",
             "--class-path", cp,
              MODS_DIR.resolve("describeFoo.jmod").toString())
             .assertSuccess();

        jmod("describe",
             MODS_DIR.resolve("describeFoo.jmod").toString())
             .assertSuccess()
             .resultChecker(r -> {
                 // Expect similar output: "foo... exports jdk.test.foo ...
                 //   ... requires java.base mandated... contains jdk.test.foo.internal"
                 Pattern p = Pattern.compile("foo\\s+exports\\s+jdk.test.foo");
                 assertTrue(p.matcher(r.output).find(),
                           "Expecting to find \"foo... exports jdk.test.foo\"" +
                                "in output, but did not: [" + r.output + "]");
                 p = Pattern.compile(
                        "requires\\s+java.base\\s+mandated\\s+contains\\s+jdk.test.foo.internal");
                 assertTrue(p.matcher(r.output).find(),
                           "Expecting to find \"requires java.base mandated..., " +
                                "contains jdk.test.foo.internal ...\"" +
                                "in output, but did not: [" + r.output + "]");
             });
    }

    @Test
    public void testDuplicateEntries() throws IOException {
        Path jmod = MODS_DIR.resolve("testDuplicates.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
        Path lp = EXPLODED_DIR.resolve("foo").resolve("lib");

        jmod("create",
             "--class-path", cp + pathSeparator + cp,
             jmod.toString())
             .assertSuccess()
             .resultChecker(r ->
                 assertContains(r.output, "Warning: ignoring duplicate entry")
             );

        FileUtils.deleteFileIfExistsWithRetry(jmod);
        jmod("create",
             "--class-path", cp,
             "--libs", lp.toString() + pathSeparator + lp.toString(),
             jmod.toString())
             .assertSuccess()
             .resultChecker(r ->
                 assertContains(r.output, "Warning: ignoring duplicate entry")
             );
    }

    @Test
    public void testDuplicateEntriesFromJarFile() throws IOException {
        String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
        Path jar = Paths.get("foo.jar");
        Path jmod = MODS_DIR.resolve("testDuplicates.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jar);
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        // create JAR file
        assertTrue(JAR_TOOL.run(System.out, System.err, "cf", jar.toString(), "-C", cp, ".") == 0);

        jmod("create",
             "--class-path", jar.toString() + pathSeparator + jar.toString(),
             jmod.toString())
             .assertSuccess()
             .resultChecker(r ->
                 assertContains(r.output, "Warning: ignoring duplicate entry")
             );
    }

    @Test
    public void testIgnoreModuleInfoInOtherSections() throws IOException {
        Path jmod = MODS_DIR.resolve("testIgnoreModuleInfoInOtherSections.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();

        jmod("create",
            "--class-path", cp,
            "--libs", cp,
            jmod.toString())
            .assertSuccess()
            .resultChecker(r ->
                assertContains(r.output, "Warning: ignoring entry")
            );

        FileUtils.deleteFileIfExistsWithRetry(jmod);
        jmod("create",
             "--class-path", cp,
             "--cmds", cp,
             jmod.toString())
             .assertSuccess()
             .resultChecker(r ->
                 assertContains(r.output, "Warning: ignoring entry")
             );
    }

    @Test
    public void testLastOneWins() throws IOException {
        Path workDir = Paths.get("lastOneWins");
        if (Files.exists(workDir))
            FileUtils.deleteFileTreeWithRetry(workDir);
        Files.createDirectory(workDir);
        Path jmod = MODS_DIR.resolve("lastOneWins.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        Path cp = EXPLODED_DIR.resolve("foo").resolve("classes");
        Path bp = EXPLODED_DIR.resolve("foo").resolve("bin");
        Path lp = EXPLODED_DIR.resolve("foo").resolve("lib");
        Path cf = EXPLODED_DIR.resolve("foo").resolve("conf");

        Path shouldNotBeAdded = workDir.resolve("shouldNotBeAdded");
        Files.createDirectory(shouldNotBeAdded);
        Files.write(shouldNotBeAdded.resolve("aFile"), "hello".getBytes(UTF_8));

        // Pairs of options. For options with required arguments the last one
        // should win ( first should be effectively ignored, but may still be
        // validated ).
        jmod("create",
             "--conf", shouldNotBeAdded.toString(),
             "--conf", cf.toString(),
             "--cmds", shouldNotBeAdded.toString(),
             "--cmds", bp.toString(),
             "--libs", shouldNotBeAdded.toString(),
             "--libs", lp.toString(),
             "--class-path", shouldNotBeAdded.toString(),
             "--class-path", cp.toString(),
             "--main-class", "does.NotExist",
             "--main-class", "jdk.test.foo.Foo",
             "--module-version", "00001",
             "--module-version", "5.4.3",
             "--do-not-resolve-by-default",
             "--do-not-resolve-by-default",
             "--warn-if-resolved=incubating",
             "--warn-if-resolved=deprecated",
             MODS_DIR.resolve("lastOneWins.jmod").toString())
            .assertSuccess()
            .resultChecker(r -> {
                ModuleDescriptor md = getModuleDescriptor(jmod);
                Optional<String> omc = md.mainClass();
                assertTrue(omc.isPresent());
                assertEquals(omc.get(), "jdk.test.foo.Foo");
                Optional<Version> ov = md.version();
                assertTrue(ov.isPresent());
                assertEquals(ov.get().toString(), "5.4.3");

                try (Stream<String> s1 = findFiles(lp).map(p -> LIBS_PREFIX + p);
                     Stream<String> s2 = findFiles(cp).map(p -> CLASSES_PREFIX + p);
                     Stream<String> s3 = findFiles(bp).map(p -> CMDS_PREFIX + p);
                     Stream<String> s4 = findFiles(cf).map(p -> CONFIGS_PREFIX + p)) {
                    Set<String> expectedFilenames = Stream.concat(Stream.concat(s1,s2),
                                                                  Stream.concat(s3, s4))
                                                          .collect(toSet());
                    assertJmodContent(jmod, expectedFilenames);
                }
            });

        jmod("extract",
             "--dir", "blah",
             "--dir", "lastOneWinsExtractDir",
             jmod.toString())
            .assertSuccess()
            .resultChecker(r -> {
                assertTrue(Files.exists(Paths.get("lastOneWinsExtractDir")));
                assertTrue(Files.notExists(Paths.get("blah")));
            });
    }

    @Test
    public void testPackagesAttribute() throws IOException {
        Path jmod = MODS_DIR.resolve("foo.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();

        Set<String> expectedPackages = Set.of("jdk.test.foo",
                                              "jdk.test.foo.internal",
                                              "jdk.test.foo.resources");

        jmod("create",
             "--class-path", cp,
             jmod.toString())
             .assertSuccess()
             .resultChecker(r -> {
                 Set<String> pkgs = getModuleDescriptor(jmod).packages();
                 assertEquals(pkgs, expectedPackages);
             });
    }

    /**
     * Test class files is the META-INF directory.
     */
    @Test
    public void testClassInMetaInf() throws IOException {
        Path jmod = MODS_DIR.resolve("baz.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);

        ModuleDescriptor descriptor = ModuleDescriptor.newModule("baz").build();
        byte[] moduleInfo = ModuleInfoWriter.toBytes(descriptor);

        Path dir = Files.createTempDirectory(Path.of("."), "baz");
        Files.write(dir.resolve("module-info.class"), moduleInfo);
        Files.createFile(Files.createDirectory(dir.resolve("p")).resolve("C.class"));

        // META-INF/extra/q/C.class
        Path extraClasses = dir.resolve("META-INF/extra/");
        Files.createFile(Files.createDirectories(extraClasses.resolve("q")).resolve("C.class"));

        Set<String> expectedPackages = Set.of("p");
        Set<String> expectedContent = Set.of(
                CLASSES_PREFIX + "module-info.class",
                CLASSES_PREFIX + "p/C.class",
                CLASSES_PREFIX + "META-INF/extra/q/C.class");

        jmod("create",
                "--class-path", dir.toString(),
                jmod.toString())
                .assertSuccess()
                .resultChecker(r -> {
                    Set<String> pkgs = getModuleDescriptor(jmod).packages();
                    assertEquals(pkgs, expectedPackages);
                    assertJmodContent(jmod, expectedContent);
                });
    }

    @Test
    public void testVersion() {
        jmod("--version")
            .assertSuccess()
            .resultChecker(r -> {
                assertContains(r.output, System.getProperty("java.version"));
            });
    }

    @Test
    public void testHelp() {
        jmod("--help")
            .assertSuccess()
            .resultChecker(r -> {
                assertTrue(r.output.startsWith("Usage: jmod"), "Help not printed");
                assertFalse(r.output.contains("--do-not-resolve-by-default"));
                assertFalse(r.output.contains("--warn-if-resolved"));
            });
    }

    @Test
    public void testHelpExtra() {
        jmod("--help-extra")
            .assertSuccess()
            .resultChecker(r -> {
                assertTrue(r.output.startsWith("Usage: jmod"), "Extra help not printed");
                assertContains(r.output, "--do-not-resolve-by-default");
                assertContains(r.output, "--warn-if-resolved");
            });
    }

    @Test
    public void testTmpFileRemoved() throws IOException {
        // Implementation detail: jmod tool creates <jmod-file>.tmp
        // Ensure that it is removed in the event of a failure.
        // The failure in this case is a class in the unnamed package.

        Path jmod = MODS_DIR.resolve("testTmpFileRemoved.jmod");
        Path tmp = MODS_DIR.resolve(".testTmpFileRemoved.jmod.tmp");
        FileUtils.deleteFileIfExistsWithRetry(jmod);
        FileUtils.deleteFileIfExistsWithRetry(tmp);
        String cp = EXPLODED_DIR.resolve("foo").resolve("classes") + File.pathSeparator +
                    EXPLODED_DIR.resolve("foo").resolve("classes")
                                .resolve("jdk").resolve("test").resolve("foo").toString();

        jmod("create",
             "--class-path", cp,
             jmod.toString())
            .assertFailure()
            .resultChecker(r -> {
                assertContains(r.output, "unnamed package");
                assertTrue(Files.notExists(tmp), "Unexpected tmp file:" + tmp);
            });
    }

    @Test
    public void testCompressionLevel() throws IOException {
        String cp = EXPLODED_DIR.resolve("foo").resolve("classes").toString();
        Path jmod = MODS_DIR.resolve("foo.jmod");
        FileUtils.deleteFileIfExistsWithRetry(jmod);

        jmod("create",
             "--class-path", cp,
             "--compress", "zip-0",
             jmod.toString())
            .assertSuccess();

        jmod("list",
             "--compress", "zip-0",
             jmod.toString())
            .assertFailure()
            .resultChecker(r -> {
                assertTrue(r.output.contains("--compress is only accepted with create mode"), "Error message printed");
            });

        FileUtils.deleteFileIfExistsWithRetry(jmod);

        jmod("create",
             "--class-path", cp,
             "--compress", "zip-9",
             jmod.toString())
            .assertSuccess();

        FileUtils.deleteFileIfExistsWithRetry(jmod);

        jmod("create",
             "--class-path", cp,
             "--compress", "zip--1",
             jmod.toString())
            .assertFailure()
            .resultChecker(r -> {
                assertTrue(r.output.contains("--compress value is invalid"), "Error message printed");
            });

        FileUtils.deleteFileIfExistsWithRetry(jmod);

        jmod("create",
             "--class-path", cp,
             "--compress", "zip-1-something",
             jmod.toString())
            .assertFailure()
            .resultChecker(r -> {
                assertTrue(r.output.contains("--compress value is invalid"), "Error message printed");
            });

        FileUtils.deleteFileIfExistsWithRetry(jmod);

        jmod("create",
             "--class-path", cp,
             "--compress", "zip-10",
             jmod.toString())
            .assertFailure()
            .resultChecker(r -> {
                assertTrue(r.output.contains("--compress value is invalid"), "Error message printed");
            });

        FileUtils.deleteFileIfExistsWithRetry(jmod);

        jmod("create",
             "--class-path", cp,
             "--compress", "zip-",
             jmod.toString())
            .assertFailure()
            .resultChecker(r -> {
                assertTrue(r.output.contains("--compress value is invalid"), "Error message printed");
            });

        FileUtils.deleteFileIfExistsWithRetry(jmod);

        jmod("create",
             "--class-path", cp,
             "--compress", "test",
             jmod.toString())
            .assertFailure()
            .resultChecker(r -> {
                assertTrue(r.output.contains("--compress value is invalid"), "Error message printed");
            });

        FileUtils.deleteFileIfExistsWithRetry(jmod);

        jmod("create",
             "--class-path", cp,
             "--compress", "test-0",
             jmod.toString())
            .assertFailure()
            .resultChecker(r -> {
                assertTrue(r.output.contains("--compress value is invalid"), "Error message printed");
            });
    }

    // ---

    static boolean compileModule(String name, Path dest) throws IOException {
        return CompilerUtils.compile(SRC_DIR.resolve(name), dest);
    }

    static void assertContains(String output, String subString) {
        if (output.contains(subString))
            assertTrue(true);
        else
            assertTrue(false,"Expected to find [" + subString + "], in output ["
                           + output + "]" + "\n");
    }

    static ModuleDescriptor getModuleDescriptor(Path jmod) {
        ClassLoader cl = ClassLoader.getSystemClassLoader();
        try (FileSystem fs = FileSystems.newFileSystem(jmod, cl)) {
            String p = "/classes/module-info.class";
            try (InputStream is = Files.newInputStream(fs.getPath(p))) {
                return ModuleDescriptor.read(is);
            }
        } catch (IOException ioe) {
            throw new UncheckedIOException(ioe);
        }
    }

    static Stream<String> findFiles(Path dir) {
        try {
            return Files.find(dir, Integer.MAX_VALUE, (p, a) -> a.isRegularFile())
                        .map(dir::relativize)
                        .map(Path::toString)
                        .map(p -> p.replace(File.separator, "/"));
        } catch (IOException x) {
            throw new UncheckedIOException(x);
        }
    }

    static Set<String> getJmodContent(Path jmod) {
        JmodResult r = jmod("list", jmod.toString()).assertSuccess();
        return Stream.of(r.output.split("\r?\n")).collect(toSet());
    }

    static void assertJmodContent(Path jmod, Set<String> expected) {
        Set<String> actual = getJmodContent(jmod);
        if (!Objects.equals(actual, expected)) {
            Set<String> unexpected = new HashSet<>(actual);
            unexpected.removeAll(expected);
            Set<String> notFound = new HashSet<>(expected);
            notFound.removeAll(actual);
            StringBuilder sb = new StringBuilder();
            sb.append("Unexpected but found:\n");
            unexpected.forEach(s -> sb.append("\t" + s + "\n"));
            sb.append("Expected but not found:\n");
            notFound.forEach(s -> sb.append("\t" + s + "\n"));
            assertTrue(false, "Jmod content check failed.\n" + sb.toString());
        }
    }

    static void assertJmodDoesNotContain(Path jmod, Set<String> unexpectedNames) {
        Set<String> actual = getJmodContent(jmod);
        Set<String> unexpected = new HashSet<>();
        for (String name : unexpectedNames) {
            if (actual.contains(name))
                unexpected.add(name);
        }
        if (!unexpected.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            for (String s : unexpected)
                sb.append("Unexpected but found: " + s + "\n");
            sb.append("In :");
            for (String s : actual)
                sb.append("\t" + s + "\n");
            assertTrue(false, "Jmod content check failed.\n" + sb.toString());
        }
    }

    static void assertSameContent(Path p1, Path p2) {
        try {
            byte[] ba1 = Files.readAllBytes(p1);
            byte[] ba2 = Files.readAllBytes(p2);
            assertEquals(ba1, ba2);
        } catch (IOException x) {
            throw new UncheckedIOException(x);
        }
    }

    static JmodResult jmod(String... args) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(baos);
        System.out.println("jmod " + Arrays.asList(args));
        int ec = JMOD_TOOL.run(ps, ps, args);
        return new JmodResult(ec, new String(baos.toByteArray(), UTF_8));
    }

    static class JmodResult {
        final int exitCode;
        final String output;

        JmodResult(int exitValue, String output) {
            this.exitCode = exitValue;
            this.output = output;
        }
        JmodResult assertSuccess() { assertTrue(exitCode == 0, output); return this; }
        JmodResult assertFailure() { assertTrue(exitCode != 0, output); return this; }
        JmodResult resultChecker(Consumer<JmodResult> r) { r.accept(this); return this; }
    }

    static void createCmds(Path dir) throws IOException {
        List<String> files = Arrays.asList(
                "first", "second", "third" + File.separator + "third");
        createFiles(dir, files);
    }

    static void createLibs(Path dir) throws IOException {
        List<String> files = Arrays.asList(
                "first.so", "second.so", "third" + File.separator + "third.so");
        createFiles(dir, files);
    }

    static void createConfigs(Path dir) throws IOException {
        List<String> files = Arrays.asList(
                "first.cfg", "second.cfg", "third" + File.separator + "third.cfg");
        createFiles(dir, files);
    }

    static void createFiles(Path dir, List<String> filenames) throws IOException {
        for (String name : filenames) {
            Path file = dir.resolve(name);
            Files.createDirectories(file.getParent());
            Files.createFile(file);
            try (OutputStream os  = Files.newOutputStream(file)) {
                os.write("blahblahblah".getBytes(UTF_8));
            }
        }
    }

    static void copyResource(Path srcDir, Path dir, String resource) throws IOException {
        Path dest = dir.resolve(resource);
        Files.deleteIfExists(dest);

        Files.createDirectories(dest.getParent());
        Files.copy(srcDir.resolve(resource), dest);
    }

    // Standalone entry point.
    public static void main(String[] args) throws Throwable {
        JmodTest test = new JmodTest();
        test.buildExplodedModules();
        for (Method m : JmodTest.class.getDeclaredMethods()) {
            if (m.getAnnotation(Test.class) != null) {
                System.out.println("Invoking " + m.getName());
                m.invoke(test);
            }
        }
    }
}
