import java.io.File;
import java.io.FileOutputStream;
import java.lang.module.ModuleFinder;
import java.nio.file.Files;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Proof {

    private static final String ROOT_FOLDER = ".";
    private static final String TEST_FOLDER = "test";
    private static final String MODULE_FOLDER = "modul";
    private static final String PACKAGE_NAME = "somepackage";
    private static final String META_INF = "META-INF";
    private static final String MANIFEST = "Manifest-Version: 1.0\n" +
                                           "Automatic-Module-Name: automatic.modul\n";
    private static final String RESOURCE_NAME = "res.txt";
    private static final String RESOURCE_CONTENT = "somecontent";

    private static final String JAR_NAME = "auto-1.0.0.jar";

    public static void main(String[] args) throws Exception {

        File root = new File(ROOT_FOLDER);

        File testFolder = new File(root, TEST_FOLDER);
        testFolder.mkdirs();

        File parentFolder = new File(testFolder, "parent");
        parentFolder.mkdirs();

        File moduleFolder = new File(parentFolder, MODULE_FOLDER);
        moduleFolder.mkdirs();

        File packageFolder = new File(moduleFolder, PACKAGE_NAME);
        packageFolder.mkdirs();

        File metaFolder = new File(moduleFolder, META_INF);
        metaFolder.mkdirs();

        File manifestFile = new File(metaFolder, "MANIFEST.MF");

        File resourceFile = new File(packageFolder, RESOURCE_NAME);

        //create the MANIFEST.MF
        Files.write(manifestFile.toPath(), MANIFEST.getBytes());

        //add resource in package
        Files.write(resourceFile.toPath(), RESOURCE_CONTENT.getBytes());

        //create the jar file
        File jarFile = new File(testFolder, JAR_NAME);
        try (FileOutputStream fos = new FileOutputStream(jarFile);
             ZipOutputStream zos = new ZipOutputStream(fos)) {

            // add manifest
            ZipEntry ze = new ZipEntry(META_INF + "/" + manifestFile.getName());
            zos.putNextEntry(ze);
            zos.write(Files.readAllBytes(manifestFile.toPath()));
            zos.closeEntry();

            // add simple resource
            ze = new ZipEntry(PACKAGE_NAME + "/" + resourceFile.getName());
            zos.putNextEntry(ze);
            zos.write(Files.readAllBytes(resourceFile.toPath()));
            zos.closeEntry();
        }

        System.out.println("\n\nFind the automatic module from the jar\n");
        var setOfFoundModule = ModuleFinder.of(jarFile.toPath()).findAll();
        if (setOfFoundModule.isEmpty()) {
            System.out.println("I found nothing when a jar file is provided");
        } else {
            System.out.println("I found something when a jar file is provided");
            setOfFoundModule.forEach(m -> System.out.println("I found:" + m.descriptor().name()));
        }

        System.out.println("\n\nFind the automatic module from module folder\n");
        setOfFoundModule = ModuleFinder.of(moduleFolder.toPath()).findAll();
        if (setOfFoundModule.isEmpty()) {
            System.out.println("I found nothing when an exploded module is provided");
        } else {
            System.out.println("I found something when an exploded module is provided");
            setOfFoundModule.forEach(m -> System.out.println("I found:" + m.descriptor().name()));
        }

        System.out.println("\n\nFind the automatic module from the parent of the module folder\n");
        setOfFoundModule = ModuleFinder.of(parentFolder.toPath()).findAll();
        if (setOfFoundModule.isEmpty()) {
            System.out.println("I found nothing when the parent folder of an exploded module is provided");
        } else {
            System.out.println("I found something when the parent folder of an exploded module is provided");
            setOfFoundModule.forEach(m -> System.out.println("I found:" + m.descriptor().name()));
        }
    }

}
