/*
 * Copyright (c) 2016, 2024, 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.
 */

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Properties;
import java.util.spi.ToolProvider;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import tests.Helper;
import tests.JImageGenerator;
import tests.JImageGenerator.JLinkTask;

/*
 * @test
 * @bug 8168925
 * @summary MODULES property should be topologically ordered and space-separated list
 * @library ../lib
 * @modules java.base/jdk.internal.jimage
 *          jdk.jlink/jdk.tools.jlink.internal
 *          jdk.jlink/jdk.tools.jmod
 *          jdk.jlink/jdk.tools.jimage
 *          jdk.compiler
 *          jdk.jshell
 *
 * @build tests.*
 * @run main ModuleNamesOrderTest
 */
public class ModuleNamesOrderTest {
    static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
        .orElseThrow(() ->
            new RuntimeException("jlink tool not found")
        );

    public static void main(String[] args) throws Exception {
        Helper helper = Helper.newHelper();
        if (helper == null) {
            System.err.println("Test not run");
            return;
        }

        testDependences(helper);
        testModulesOrder(helper);
    }

    private static List<String> modulesProperty(Path outputDir, String modulePath, String... roots)
        throws IOException
    {
        JLinkTask jlinkTask = JImageGenerator.getJLinkTask()
                                             .modulePath(modulePath)
                                             .output(outputDir);
        Stream.of(roots).forEach(jlinkTask::addMods);
        jlinkTask.call().assertSuccess();

        File release = new File(outputDir.toString(), "release");
        if (!release.exists()) {
            throw new AssertionError("release not generated");
        }

        Properties props = new Properties();
        try (FileReader reader = new FileReader(release)) {
            props.load(reader);
        }

        String modules = props.getProperty("MODULES");
        if (!modules.startsWith("\"java.base ")) {
            throw new AssertionError("MODULES should start with 'java.base'");
        }
        if (modules.charAt(0) != '"' || modules.charAt(modules.length()-1) != '"') {
            throw new AssertionError("MODULES value should be double quoted");
        }

        return Stream.of(modules.substring(1, modules.length()-1).split("\\s+"))
                     .collect(Collectors.toList());
    }

    private static void testDependences(Helper helper) throws IOException {
        Path outputDir = helper.createNewImageDir("test");
        List<String> modules = modulesProperty(outputDir, helper.defaultModulePath(),
            "jdk.jshell");
        String last = modules.get(modules.size()-1);
        if (!last.equals("jdk.jshell")) {
            throw new AssertionError("Unexpected MODULES value: " + modules);
        }

        checkDependency(modules, "java.logging", "java.base");
        checkDependency(modules, "jdk.compiler", "java.compiler");
        checkDependency(modules, "jdk.jshell", "java.logging");
        checkDependency(modules, "jdk.jshell", "jdk.compiler");
    }

    /*
     * Verify the MODULES list must be the same for the same module graph
     */
    private static void testModulesOrder(Helper helper) throws IOException {
        Path image1 = helper.createNewImageDir("test1");
        List<String> modules1 = modulesProperty(image1, helper.defaultModulePath(),
            "jdk.jshell");
        Path image2 = helper.createNewImageDir("test2");
        List<String> modules2 = modulesProperty(image2, helper.defaultModulePath(),
            "jdk.jshell");
        if (!modules1.equals(modules2)) {
            throw new AssertionError("MODULES should be a stable order: " +
                modules1 + " vs " + modules2);
        }
    }

    private static void checkDependency(List<String> modules, String fromMod, String toMod) {
        int fromModIdx = modules.indexOf(fromMod);
        if (fromModIdx == -1) {
            throw new AssertionError(fromMod + " is missing in MODULES");
        }
        int toModIdx = modules.indexOf(toMod);
        if (toModIdx == -1) {
            throw new AssertionError(toMod + " is missing in MODULES");
        }

        if (toModIdx > fromModIdx) {
            throw new AssertionError("in MODULES, " + fromMod + " should appear after " + toMod);
        }
    }
}
