/*
 * Copyright (c) 2003, 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
 */

package devtests.deployment.jsr88.apitests;

import java.io.*;
import java.util.*;
import javax.enterprise.deploy.spi.*;
import javax.enterprise.deploy.spi.status.ProgressEvent;
import javax.enterprise.deploy.spi.status.DeploymentStatus;
import javax.enterprise.deploy.shared.ModuleType;
import devtests.deployment.util.JSR88Deployer;

public class TestClient {

        /**
         *system property (integer) specifying the sleep delay to introduce into ProgressobjectImpl event notification
         *to make sure a possible race condition does not occur.  The property also has a default value.
         */
        private final String SLEEP_TIME_PROPERTY_NAME = "devtests.sleepDurationForProgressObjectImplRaceTest";
        private final Integer SLEEP_TIME_DEFAULT = new Integer(4000);

        JSR88Deployer depl = null;

    private void initDeployer(String[] args) throws Exception {
        log("Getting access to JSR88 deployer: using URI = " + args[1]);
        depl = new JSR88Deployer(args[1], args[2], args[3]);
    }

    private boolean checkIfAppsArePresent(TargetModuleID[] reportedApps, HashMap expectedApps) {
        for(int i=0; i<reportedApps.length; i++) {
            String modId = reportedApps[i].getModuleID();
            log("Reported application  name = " + modId);
            if(expectedApps.containsKey(modId))
                expectedApps.remove(modId);
        }
        if(expectedApps.size() != 0) {
            log("Not all expected applications have been reported");
            return(false);
        }
        log("All expected applications have been reported");
        return(true);
    }
    
    private boolean checkReportedApps(String[] args, Boolean state)
                                                    throws Exception {
        log("Checking if application names reported are valid");

        HashMap set = new HashMap();
        set.put(args[4], "app");
        set.put(args[5], "app");
        set.put(args[6], "app");

        TargetModuleID[] apps = depl.getAllApplications(state);
        log("Total count = " + apps.length);
        return(checkIfAppsArePresent(apps, set));
    }

    private int testProgressObjectImplRace(String[] args) throws Exception {
        /*
         *This test works like testStartStop except that it uses only one application and sets the system
         *property to introduce a sleep into listener notification to test race conditions.  See ProgressObjectImpl
         *for more details on the possible problem and how the test probes for it.
         */
        String appOfInterest = args[4];
        boolean appIsRunning = true;

        try {
            /*
             *The system property to control the test code in ProgressObjectImpl could have been set on the
             *command line that ran this test.  If not, use the default value.
             */
            Integer sleepTime = Integer.getInteger(SLEEP_TIME_PROPERTY_NAME, SLEEP_TIME_DEFAULT);
            log("ProgressObjectImpl race test is using " + SLEEP_TIME_PROPERTY_NAME + " = " + sleepTime);

            /*
             *Stop the first application specified on the command line.
             */
            log("Stopping application " + appOfInterest);
            if (depl.stop(appOfInterest) == null) {
                log("Failed to stop " + appOfInterest);
                return -1;
            }
            log("Stop request completed");

            /*
             *Wait a while for the stop operation to complete and the events to be delivered.
             */
            try {
                Thread.currentThread().sleep(sleepTime.intValue());
            } catch (InterruptedException ie) {
                log("ProgressObjectImpl race test was interrupted during a sleep waiting for the app to stop.");
                return -1;
            }

            appIsRunning = false;

            /*
             *Now that the app is stopped, start it and pay attention to the events.
             */
            log("Starting application " + appOfInterest);
            depl.clearReceivedEvents();
            if (depl.start(appOfInterest, sleepTime.intValue() / 2 ) == null) {
                log("Failed to start " + appOfInterest);
                return -1;
            }

            appIsRunning = true;

            /*
             *Wait before retrieving the events to give the start operation time to complete.
             */

            try {
                Thread.currentThread().sleep(sleepTime.intValue());
            } catch (InterruptedException ie) {
                throw new RuntimeException("TestClient was interrupted waiting for start operation events to accumulate before retrieving them.", ie);
            }

            log("About to retrieve events");
            ProgressEvent receivedEvents[] = depl.getReceivedEvents();

            /*
             *We expect two events, one corresponding to the start operation entering the "running" state and
             *one for the operation completing.  If the race condition has occurred, then we won't see both of 
             *the events.  We're going to look at the first one, expecting it to be the "running" event.
             */
            if (receivedEvents.length < 2) {
                log("ProgressObjectImpl race test expected two events (running and completed), but found " + receivedEvents.length + ".");
                if (receivedEvents.length == 1) {
                    log("...and the event that was recorded was " + receivedEvents[0].getDeploymentStatus().getMessage());
                }
                return -1;
            }

            ProgressEvent event = receivedEvents[0];
            DeploymentStatus dStatus = event.getDeploymentStatus();

            if ( ! dStatus.isRunning()) {
                log("ProgressObjectImpl race test's first recorded event was not what was expected; expected running but found " + dStatus.getMessage());
                return -1;
            } else {
                log("ProgressObjectImpl race test completed normally.");
                return 0;
            }

        } finally {
            /*
             *Restart the application if it isn't running.
             */
            if ( ! appIsRunning) {
                log("Restarting application " + appOfInterest);
                if (depl.start(appOfInterest) == null) {
                    log("Failed to restart application " + appOfInterest);
                    return -1;
                }
            }
        }
    }
        
    private int testStartStop(String[] args) {
        try {
            log("Stopping all Applications");
            for(int i=4; i<7; i++) {
                if(depl.stop(args[i]) == null) {
                    log("Failed to stop " + args[i]);
                    return(-1);
                }
            }
            boolean ret = checkReportedApps(args, Boolean.FALSE);
            if(!ret)
                return(-1);
            log("Starting all Applications");
            for(int j=4; j<7; j++) {
                if (depl.start(args[j]) == null) {;
                    log("Failed to start " + args[j]);
                    return(-1);
                }
            }
            ret = checkReportedApps(args, Boolean.TRUE);
            if(!ret)
                return(-1);
        } catch(Exception e) {
            log("testStartStop recd exception : " + e.getMessage());
            return(-1);
        }
        return(0);
    }

    private int getModulesByType(String args[], ModuleType type, Boolean state) {
        log("Getting list of Applications with type = " + type.toString());
        log("Required running state = " + state);
        try {
            TargetModuleID[] apps = depl.getApplications(type, state);
            log("Total count = " + apps.length);

            HashMap set = new HashMap();
            set.put(args[4], "app");
            
            boolean ret = checkIfAppsArePresent(apps, set);
            if(!ret)
                return(-1);
        } catch(Exception e) {
            log("getModulesByType recd exception : " + e.getMessage());
            return(-1);
        }
        return(0);
    }

    private int testEmptyModule() {
        try {
            TargetModuleID[] apps = depl.getApplications(ModuleType.WAR, null);
            if(apps.length != 0) {
                log("# of WARs expected = 0");
                log("# of WARs reported = " + apps.length);
                return(-1);
            }
            apps = depl.getApplications(ModuleType.EJB, null);
            if(apps.length != 0) {
                log("# of EJB-JARs expected = 0");
                log("# of EJB-JARs reported = " + apps.length);
                return(-1);
            }
            apps = depl.getApplications(ModuleType.EAR, null);
            if(apps.length != 0) {
                log("# of EARs expected = 0");
                log("# of EARs reported = " + apps.length);
                return(-1);
            }
        } catch(Exception e) {
            log("testEmptyModule recd exception : " + e.getMessage());
            return(-1);
        }
        return(0);
    }

    public static void main(String[] args) {
        int exitVal = 0;
        TestClient client = new TestClient();
        try {
            int testCase = (new Integer(args[0])).intValue();
            client.initDeployer(args);
            switch(testCase) {
                case 1 :
                    exitVal = client.getModulesByType(args,ModuleType.WAR,null);
                    break;
                case 2 :
                    exitVal = client.getModulesByType(args,ModuleType.EJB,null);
                    break;
                case 3 :
                    exitVal = client.getModulesByType(args,ModuleType.EAR,null);
                    break;
                case 4 :
                    exitVal = client.testStartStop(args);
                    break;
                case 5 :
                    exitVal = client.testEmptyModule();
                    break;
                case 6 :
                        exitVal = client.testProgressObjectImplRace(args);
                        break;
                default:
                    log("Wrong test number given !!!");
                    exitVal = -1;
                    break;
            }
        } catch (Exception e) {
            log("Caught Exception = " + e.getMessage());
            System.exit(-1);
        }
        System.exit(exitVal);
    }

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