package liquibase.example;

import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.DriverManager;

/**
 * Wrapper around the h2 console for use in the "examples" directory
 */
@SuppressWarnings("java:S2189")
public class StartH2Main {

    private static final String dbPort = "9090";
    private static final String webPort = "8090";
    private static final String username = "dbuser";
    private static final String password = "letmein";

    public static void main(String[] args) throws Exception {
        System.out.println("Starting Example H2 Database...");
        System.out.println("NOTE: The database does not persist data, so stopping and restarting this process will reset it back to a blank database");
        System.out.println();

        Class.forName("org.h2.Driver");

        try (Connection devConnection = DriverManager.getConnection("jdbc:h2:mem:dev", username, password);
             Connection intConnection = DriverManager.getConnection("jdbc:h2:mem:integration", username, password)) {

            startTcpServer();

            Object webServer = startWebServer();
            String devUrl = createWebSession(devConnection, webServer, true);
            String intUrl = createWebSession(intConnection, webServer, false);

            System.out.println("Connection Information:" + System.lineSeparator() +
                    "  Dev database: " + System.lineSeparator() +
                    "    JDBC URL: jdbc:h2:tcp://localhost:" + dbPort + "/mem:dev" + System.lineSeparator() +
                    "    Username: " + username + System.lineSeparator() +
                    "    Password: " + password + System.lineSeparator() +
                    "  Integration database: " + System.lineSeparator() +
                    "    JDBC URL: jdbc:h2:tcp://localhost:" + dbPort + "/mem:integration" + System.lineSeparator() +
                    "    Username: " + username + System.lineSeparator() +
                    "    Password: " + password + System.lineSeparator() +
                    "" + System.lineSeparator() +
                    "Opening Database Console in Browser..." + System.lineSeparator() +
                    "  Dev Web URL: " + devUrl + System.lineSeparator() +
                    "  Integration Web URL: " + intUrl + System.lineSeparator());


            long seconds = 60;
            long millis = 1000;
            while (true) {
                try {
                    Thread.sleep(seconds * millis);
                } catch (InterruptedException interruptedException) {
                    Thread.currentThread().interrupt();
                }
            }

        } catch (Throwable e) {
            e.printStackTrace();
            System.exit(-1);
        }


    }

    protected static void startTcpServer() throws Exception {
        final Class<?> serverClass = Class.forName("org.h2.tools.Server");
        final Object tcpServer = serverClass.getMethod("createTcpServer", String[].class)
                .invoke(null, (Object) new String[]{"-tcpAllowOthers", "-tcpPort", dbPort});

        tcpServer.getClass().getMethod("start")
                .invoke(tcpServer);
    }

    protected static Object startWebServer() throws Exception {
        final Class<?> serverClass = Class.forName("org.h2.tools.Server");

        final Object webServer = Class.forName("org.h2.server.web.WebServer").newInstance();
        Object web = serverClass.getConstructor(Class.forName("org.h2.server.Service"), String[].class).newInstance(webServer, (Object) new String[]{"-webPort", webPort});
        web.getClass().getMethod("start").invoke(web);

        return webServer;
    }

    private static String createWebSession(Connection connection, Object webServer, boolean openBrowser) throws Exception {
        final Class<?> serverClass = Class.forName("org.h2.tools.Server");

        String url = (String) webServer.getClass().getMethod("addSession", Connection.class).invoke(webServer, connection);

        if (openBrowser) {
            try {
                serverClass.getMethod("openBrowser", String.class).invoke(null, url);
            } catch (Exception e) {
                String message = e.getMessage();
                if (message == null && e.getCause() != null) {
                    message = e.getCause().getMessage();
                }
                System.out.println("Cannot open browser: "+ message);
                System.out.println("");
            }
        }

        return url;
    }

}
@@ -131,16 +131,54 @@
 Manager;
+%0Aimport java.util.concurrent.TimeUnit;
 %0A%0A/**%0A *
@@ -819,24 +819,42 @@
 println();%0A%0A
+        try %7B%0A    
         Clas
@@ -876,24 +876,408 @@
 h2.Driver%22);
+%0A        %7D catch (ClassNotFoundException e) %7B%0A            String msg = %22ERROR: H2 was not configured properly. To use Liquibase and H2, you need to have the JDBC driver .jar file. Liquibase includes the H2 in-memory database and the h2-%3Cversion%3E.jar file in liquibase/lib. Learn more at https://docs.liquibase.com/%22;%0A            System.out.println(msg);%0A            throw e;%0A        %7D
 %0A%0A        tr
@@ -2783,71 +2783,8 @@
 ;%0A%0A%0A
-            long seconds = 60;%0A            long millis = 1000;%0A
     
@@ -2865,24 +2865,37 @@
 eep(
-seconds * m
+TimeUnit.SECONDS.toM
 illis
+(60)
 );%0A 

print a pretty error if the H2 jar cannot be found (#2311)