package org.keycloak.quarkus._private;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import org.keycloak.quarkus.runtime.KeycloakMain;
import org.keycloak.quarkus.runtime.cli.Picocli;

import io.quarkus.runtime.Quarkus;

/**
 * <p>This main class should be used to start the server in dev mode for development purposes. By running this class,
 * developers should be able to mimic any server behavior and configuration as if they were using the CLI.
 *
 * <p>There are some limitations during development such as:
 *
 * <ul>
 *     <li>Transient dependencies from the keycloak server extension (runtime module) are not eligible for hot-reload</li>
 *     <li>Code changes such as changing the structure of classes (e.g.: new/change methods) should still require a JVM restart</li>
 * </ul>
 *
 * <p>Despite the limitations, it should be possible to debug the extension (e.g.: deployment steps) as well as perform changes at runtime
 * without having to restart the JVM.
 *
 * @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
 */
public class IDELauncher {

    public static void main(String[] args) {
        if (System.getProperty("java.util.logging.manager") == null) {
            System.setProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager");
        }

        if (System.getProperty("picocli.disable.closures") == null) {
            System.setProperty("picocli.disable.closures", "true");
        }

        if (System.getProperty("java.util.concurrent.ForkJoinPool.common.threadFactory") == null) {
            System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory", "io.quarkus.bootstrap.forkjoin.QuarkusForkJoinWorkerThreadFactory");
        }

        List<String> devArgs = new ArrayList<>(Picocli.parseArgs(args));

        if (System.getProperty("kc.home.dir") == null) {
            // direct the auto-created files to the target folder, so they are cleaned by "mvn clean"
            // users can still provide a different folder by setting the property when starting it from their IDE.
            Path path = Paths.get(System.getProperty("user.dir"), "target", "kc");
            System.setProperty("kc.home.dir", path.toAbsolutePath().toString());
        }

        if (devArgs.isEmpty()) {
            devArgs.add("start-dev");
        }

        Quarkus.run(KeycloakMain.class, devArgs.toArray(new String[devArgs.size()]));
    }
}
