/*
 * Copyright (c) 2015, 2023, 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 8300228
 * @library /test/lib
 * @modules java.base/jdk.internal.module
 *          jdk.compiler
 *          jdk.jlink
 * @build ModuleReaderTest
 *        jdk.test.lib.compiler.CompilerUtils
 *        jdk.test.lib.util.JarUtils
 * @run testng ModuleReaderTest
 * @summary Basic tests for java.lang.module.ModuleReader
 */

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReader;
import java.lang.module.ModuleReference;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.spi.ToolProvider;
import java.util.stream.Stream;

import jdk.internal.module.ModulePath;
import jdk.test.lib.compiler.CompilerUtils;
import jdk.test.lib.util.JarUtils;

import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import static org.testng.Assert.*;

public class ModuleReaderTest {
    private static final String TEST_SRC = System.getProperty("test.src");

    private static final Path USER_DIR   = Paths.get(System.getProperty("user.dir"));
    private static final Path SRC_DIR    = Paths.get(TEST_SRC, "src");
    private static final Path MODS_DIR   = Paths.get("mods");

    // the module name of the base module
    private static final String BASE_MODULE = "java.base";

    // the module name of the test module
    private static final String TEST_MODULE = "m";

    // resources in the base module
    private static final String[] BASE_RESOURCES = {
        "java/lang/Object.class"
    };

    // (directory) resources that may be in the base module
    private static final String[] MAYBE_BASE_RESOURCES = {
        "java",
        "java/",
        "java/lang",
        "java/lang/",
    };

    // resource names that should not be found in the base module
    private static final String[] NOT_BASE_RESOURCES = {
        "NotFound",
        "/java",
        "//java",
        "/java/lang",
        "//java/lang",
        "java//lang",
        "/java/lang/Object.class",
        "//java/lang/Object.class",
        "java/lang/Object.class/",
        "java//lang//Object.class",
        "./java/lang/Object.class",
        "java/./lang/Object.class",
        "java/lang/./Object.class",
        "../java/lang/Object.class",
        "java/../lang/Object.class",
        "java/lang/../Object.class",

        // junk resource names
        "java\u0000",
        "C:java",
        "C:\\java",
        "java\\lang\\Object.class"
    };

    // resources in test module (can't use module-info.class as a test
    // resource as it will be modified by the jmod tool)
    private static final String[] TEST_RESOURCES = {
        "p/Main.class"
    };

    // (directory) resources that may be in the test module
    private static final String[] MAYBE_TEST_RESOURCES = {
        "p",
        "p/"
    };

    // resource names that should not be found in the test module
    private static final String[] NOT_TEST_RESOURCES = {
        "NotFound",
        "/p",
        "//p",
        "/p/Main.class",
        "//p/Main.class",
        "p/Main.class/",
        "p//Main.class",
        "./p/Main.class",
        "p/./Main.class",
        "../p/Main.class",
        "p/../p/Main.class",

        // junk resource names
        "p\u0000",
        "C:p",
        "C:\\p",
        "p\\Main.class"
    };

    @BeforeTest
    public void compileTestModule() throws Exception {
        // javac -d mods/$TESTMODULE src/$TESTMODULE/**
        boolean compiled = CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE),
                                                 MODS_DIR.resolve(TEST_MODULE));
        assertTrue(compiled, "test module did not compile");
    }

    /**
     * Test ModuleReader with module in runtime image.
     */
    @Test
    public void testImage() throws IOException {
        ModuleFinder finder = ModuleFinder.ofSystem();
        ModuleReference mref = finder.find(BASE_MODULE).get();
        ModuleReader reader = mref.open();

        try (reader) {

            for (String name : BASE_RESOURCES) {
                byte[] expectedBytes;
                Module baseModule = Object.class.getModule();
                try (InputStream in = baseModule.getResourceAsStream(name)) {
                    expectedBytes = in.readAllBytes();
                }

                testFind(reader, name, expectedBytes);
                testOpen(reader, name, expectedBytes);
                testRead(reader, name, expectedBytes);
                testList(reader, name);
            }

            // test resources that may be in the base module
            for (String name : MAYBE_BASE_RESOURCES) {
                Optional<URI> ouri = reader.find(name);
                ouri.ifPresent(uri -> {
                    if (name.endsWith("/"))
                        assertTrue(uri.toString().endsWith("/"));
                });
            }

            // test "not found" in java.base module
            for (String name : NOT_BASE_RESOURCES) {
                assertFalse(reader.find(name).isPresent());
                assertFalse(reader.open(name).isPresent());
                assertFalse(reader.read(name).isPresent());
            }

            // test nulls
            try {
                reader.find(null);
                assertTrue(false);
            } catch (NullPointerException expected) { }

            try {
                reader.open(null);
                assertTrue(false);
            } catch (NullPointerException expected) { }

            try {
                reader.read(null);
                assertTrue(false);
            } catch (NullPointerException expected) { }

            try {
                reader.release(null);
                assertTrue(false);
            } catch (NullPointerException expected) { }

        }

        // test closed ModuleReader
        try {
            reader.open(BASE_RESOURCES[0]);
            assertTrue(false);
        } catch (IOException expected) { }


        try {
            reader.read(BASE_RESOURCES[0]);
            assertTrue(false);
        } catch (IOException expected) { }
    }

    /**
     * Test ModuleReader with exploded module.
     */
    @Test
    public void testExplodedModule() throws IOException {
        test(MODS_DIR);
    }

    /**
     * Test ModuleReader with module in modular JAR.
     */
    @Test
    public void testModularJar() throws IOException {
        Path dir = Files.createTempDirectory(USER_DIR, "mlib");

        // jar cf mlib/${TESTMODULE}.jar -C mods .
        JarUtils.createJarFile(dir.resolve("m.jar"),
                               MODS_DIR.resolve(TEST_MODULE));

        test(dir);
    }

    /**
     * Test ModuleReader with module in a JMOD file.
     */
    @Test
    public void testJMod() throws IOException {
        Path dir = Files.createTempDirectory(USER_DIR, "mlib");

        // jmod create --class-path mods/${TESTMODULE}  mlib/${TESTMODULE}.jmod
        String cp = MODS_DIR.resolve(TEST_MODULE).toString();
        String jmod = dir.resolve("m.jmod").toString();
        String[] args = { "create", "--class-path", cp, jmod };
        ToolProvider jmodTool = ToolProvider.findFirst("jmod")
            .orElseThrow(() ->
                new RuntimeException("jmod tool not found")
            );
        assertEquals(jmodTool.run(System.out, System.out, args), 0);

        test(dir);
    }

    /**
     * The test module is found on the given module path. Open a ModuleReader
     * to the test module and test the reader.
     */
    void test(Path mp) throws IOException {
        ModuleFinder finder = ModulePath.of(Runtime.version(), true, mp);
        ModuleReference mref = finder.find(TEST_MODULE).get();
        ModuleReader reader = mref.open();

        try (reader) {

            // test resources in test module
            for (String name : TEST_RESOURCES) {
                System.out.println("resource: " + name);
                byte[] expectedBytes
                    = Files.readAllBytes(MODS_DIR
                        .resolve(TEST_MODULE)
                        .resolve(name.replace('/', File.separatorChar)));

                testFind(reader, name, expectedBytes);
                testOpen(reader, name, expectedBytes);
                testRead(reader, name, expectedBytes);
                testList(reader, name);
            }

            // test resources that may be in the test module
            for (String name : MAYBE_TEST_RESOURCES) {
                System.out.println("resource: " + name);
                Optional<URI> ouri = reader.find(name);
                ouri.ifPresent(uri -> {
                    if (name.endsWith("/"))
                        assertTrue(uri.toString().endsWith("/"));
                });
            }

            // test "not found" in test module
            for (String name : NOT_TEST_RESOURCES) {
                System.out.println("resource: " + name);
                assertFalse(reader.find(name).isPresent());
                assertFalse(reader.open(name).isPresent());
                assertFalse(reader.read(name).isPresent());
            }

            // test nulls
            try {
                reader.find(null);
                assertTrue(false);
            } catch (NullPointerException expected) { }

            try {
                reader.open(null);
                assertTrue(false);
            } catch (NullPointerException expected) { }

            try {
                reader.read(null);
                assertTrue(false);
            } catch (NullPointerException expected) { }

            try {
                reader.release(null);
                throw new RuntimeException();
            } catch (NullPointerException expected) { }

        }

        // test closed ModuleReader
        try {
            reader.open(TEST_RESOURCES[0]);
            assertTrue(false);
        } catch (IOException expected) { }


        try {
            reader.read(TEST_RESOURCES[0]);
            assertTrue(false);
        } catch (IOException expected) { }

        try {
            reader.list();
            assertTrue(false);
        } catch (IOException expected) { }
    }

    /**
     * Test ModuleReader#find
     */
    void testFind(ModuleReader reader, String name, byte[] expectedBytes)
        throws IOException
    {
        Optional<URI> ouri = reader.find(name);
        assertTrue(ouri.isPresent());

        URL url = ouri.get().toURL();
        if (!url.getProtocol().equalsIgnoreCase("jmod")) {
            URLConnection uc = url.openConnection();
            uc.setUseCaches(false);
            try (InputStream in = uc.getInputStream()) {
                byte[] bytes = in.readAllBytes();
                assertTrue(Arrays.equals(bytes, expectedBytes));
            }
        }
    }

    /**
     * Test ModuleReader#open
     */
    void testOpen(ModuleReader reader, String name, byte[] expectedBytes)
        throws IOException
    {
        Optional<InputStream> oin = reader.open(name);
        assertTrue(oin.isPresent());

        InputStream in = oin.get();
        try (in) {
            byte[] bytes = in.readAllBytes();
            assertTrue(Arrays.equals(bytes, expectedBytes));
        }
    }

    /**
     * Test ModuleReader#read
     */
    void testRead(ModuleReader reader, String name, byte[] expectedBytes)
        throws IOException
    {
        Optional<ByteBuffer> obb = reader.read(name);
        assertTrue(obb.isPresent());

        ByteBuffer bb = obb.get();
        try {
            int rem = bb.remaining();
            assertTrue(rem == expectedBytes.length);
            byte[] bytes = new byte[rem];
            bb.get(bytes);
            assertTrue(Arrays.equals(bytes, expectedBytes));
        } finally {
            reader.release(bb);
        }
    }

    /**
     * Test ModuleReader#list
     */
    void testList(ModuleReader reader, String name) throws IOException {
        final List<String> list;
        try (Stream<String> stream = reader.list()) {
            list = stream.toList();
        }
        Set<String> names = new HashSet<>(list);
        assertTrue(names.size() == list.size()); // no duplicates

        assertTrue(names.contains("module-info.class"));
        assertTrue(names.contains(name));

        // all resources should be locatable via find
        for (String e : names) {
            assertTrue(reader.find(e).isPresent());
        }
    }

}
