/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/*
 * SimpleJSR88Client.java
 *
 *Provides access to the JSR88 API through a convenient command line.
 *<p>
 *This is intended for internal testing use only.
 *
 * Created on January 21, 2004, 11:22 AM
 */

import java.io.File;
import java.util.jar.Manifest;

import java.net.*;

import javax.enterprise.deploy.shared.ModuleType;
import javax.enterprise.deploy.spi.factories.*;
import javax.enterprise.deploy.shared.factories.*;
import javax.enterprise.deploy.spi.status.*;
import javax.enterprise.deploy.spi.*;
import javax.enterprise.deploy.spi.exceptions.*;

//import javax.enterprise.deploy.model.*;

/**
 *
 * @author  tjquinn
 */
public class SimpleJSR88Client {


    private final String J2EE_DEPLOYMENT_MANAGER = "J2EE-DeploymentFactory-Implementation-Class";

    private DeploymentFactory deploymentFactory;

    private DeploymentManager deploymentManager;

    private String host;

    private String port;

    private String user;

    private String password;

    private String uri;

    /** Creates a new instance of SimpleJSR88Client */
    public SimpleJSR88Client(String host, String port, String user, String password) {
        this.host = host;
        this.port = port;
        this.user = user;
        this.password = password;
        this.uri = "deployer:Sun:AppServer::" + host + ":" + port;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        /*
         *Get properties indicating the user, password, host, and port.
         */
        String host = null;
        String port = null;
        String user = null;
        String password = null;

        if (((host = System.getProperty("jsr88client.host")) == null)
            || ((port = System.getProperty("jsr88client.port")) == null)
            || ((user = System.getProperty("jsr88client.user")) == null)
            || ((password = System.getProperty("jsr88client.password")) == null) ) {
            System.out.println("The properties jsr88client.host, jsr88client.port, jsr88client.user, and jsr88client.password must be assigned");
            System.exit(-1);
        }

        try {
            new SimpleJSR88Client(host, port, user, password).run(args);
            System.exit(0);
        } catch (Throwable thr) {
            System.out.println("Error executing simple JSR88 client");
            thr.printStackTrace(System.out);
            System.exit(1);
        }
    }

    public void run(String[] args) throws TargetException, DeploymentManagerCreationException {
        if (args.length == 0) {
            throw new IllegalArgumentException("Specify the JSR88 client command you want to execute as the first command line parameter");
        }

        if (args[0].equals("getAvailableAppClientModules") ){
            getAvailableModules(ModuleType.CAR);
        } else {
            throw new IllegalArgumentException("Unrecognized JSR88 client command specified: " + args[0]);
        }
    }

    private void getAvailableModules(ModuleType type) throws TargetException, DeploymentManagerCreationException {
        Target targets [] = getDeploymentManager().getTargets();
        TargetModuleID [] moduleIDs = getDeploymentManager().getAvailableModules(type, targets);
        System.out.println("Available modules listing");
        for (int i = 0; i < moduleIDs.length; i++) {
            System.out.println("Module " + i + ": " + moduleIDs[i].getModuleID());
        }
        System.out.println();
    }

    private DeploymentFactory loadDeploymentFactory() {
        System.out.println("Loading deployment factory");
        Object deploymentFactory = null;
        File file = null;
        String className = null;
        try {
            file = new File(System.getProperty("com.sun.aas.installRoot")
                + File.separator+ "lib" + File.separator + "deployment"
                + File.separator + "sun-as-jsr88-dm.jar");

            Manifest mf = new java.util.jar.JarFile(file).getManifest();
            className = mf.getMainAttributes().getValue(J2EE_DEPLOYMENT_MANAGER);
            URL[] urls = new URL[]{file.toURL()};
            URLClassLoader urlClassLoader = new java.net.URLClassLoader(urls, getClass().getClassLoader());
            Class factory = null;
            try {
                factory=urlClassLoader.loadClass(className);
            } catch (ClassNotFoundException cnfe) {
                cnfe.printStackTrace();
                System.exit(-1);
            }

            try {
                deploymentFactory = factory.newInstance();
            } catch (Exception ie) {
                ie.printStackTrace();
                System.exit(-1);
            }
            if (deploymentFactory instanceof DeploymentFactory) {
                DeploymentFactoryManager.getInstance().registerDeploymentFactory((DeploymentFactory) deploymentFactory);
            } else {
                    System.out.println("Expected instance of DeploymentFactory from class loading of " + className + " but got " + deploymentFactory.getClass().getName() + " instead");
                    System.exit(-1);
            }

            } catch (Exception ex) {
                log("Failed to load the deployment factory using URL " + file.getAbsolutePath() + " and class " + className);
                ex.printStackTrace();
                System.exit(-1);
            }
            System.out.println("Deployment factory loaded.");
            return (DeploymentFactory) deploymentFactory;

    }

    private static void log(String message) {
        System.out.println("[" + getJSRClientName() + "]:: " + message);
    }

    protected static String getJSRClientName() {
        return "SimpleJSR88Client";
    }

    protected DeploymentFactory getDeploymentFactory() {
        if (this.deploymentFactory == null) {
            this.deploymentFactory = loadDeploymentFactory();
        }
        return this.deploymentFactory;
    }

    private DeploymentManager loadDeploymentManager() throws DeploymentManagerCreationException {
        System.out.println("Loading deployment manager using uri " + this.uri + " under user " + this.user);
        DeploymentManager answer = getDeploymentFactory().getDeploymentManager(this.uri, this.user, this.password);
        System.out.println("Deployment manager loaded.");
        return answer;
    }

    protected DeploymentManager getDeploymentManager() throws DeploymentManagerCreationException {
        if (this.deploymentManager == null) {
            this.deploymentManager = loadDeploymentManager();
        }
        return this.deploymentManager;
    }
}
