/*
 * 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
 */

/*
  * AutoDeployMonitor.java
  *
  * Created on May 11, 2004, 3:08 PM
  */

package autodeploy.test;

import java.util.Date;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;

import org.glassfish.deployment.autodeploy.AutoDeployConstants;

/**
  *Autodeploys an archive to the specified autodeploy directory.
 *<p>
 *To autodeploy the app, follow these steps:
 *1. Record the modification time of the archive file in the autodeploy directory as the start time.
 *2. Copy the archive to the autodeploy directory.
 *3. Monitor the autodeploy directory until it contains a marker file (for either success or
 *   failure) with a creation date and time later than the earlier-recorded timestamp.
 *4. Choose whether to return success or failure based on which kind of marker file has appeared
 *   in the autodeploy directory.
 *
  * @author  tjquinn
  */
public class AutoDeployMonitor {

    private static boolean DEBUG = Boolean.getBoolean("monitor.debug");

    private static int ITERATION_LIMIT = Integer.getInteger("monitor.iterationLimit", 60 * 2 /* default = two minutes */).intValue();

    private String archiveName = null;

//    private String autodeployDirSpec = null;

    private File autodeployDir = null;

//    private String timestampFormat = null;

//    private String timestampString = null;

    private long timestamp;

    private Date startTime = null;

    private final static String LINE_SEP = System.getProperty("line.separator");

    /** Creates a new instance of AutoDeployer */
    public AutoDeployMonitor() {
    }

    /**
      * @param args the command line arguments
      */
    public static void main(String[] args) {
        int result = new AutoDeployMonitor().run(args);
        System.exit(result);
    }

    private void processArguments(String[] args) {
        if (args.length < 4) {
            usage();
            System.exit(1);
        }

        archiveName = args[0];
        String autodeployDirSpec = args[1];
        String timestampFormat = args[2];
        String timestampString = args[3];

        autodeployDir = new File(autodeployDirSpec);

        debug("Archive to autodeploy: " + archiveName);
        debug("Autodeploy directory: " + autodeployDir.getAbsolutePath());

        StringBuffer result = new StringBuffer();

        /*
         *Check auto-deploy directory.
         */
        if ( ! autodeployDir.exists()) {
            result.append(LINE_SEP).append("Autodeploy directory " + autodeployDir.getAbsolutePath() + " does not exist but should.");
        }

        /*
         *Check archive file name.
         */
        if (archiveName.length() == 0) {
            result.append(LINE_SEP).append("Archive file name must not be empty but is.");
        }

        /*
         *Check the timestamp format and value.
         */
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timestampFormat);
        Date timestampDate = null;
        try {
            timestampDate = simpleDateFormat.parse(timestampString);
            timestamp = timestampDate.getTime();
            debug("Timestamp to use for filtering autodeploy status files: " + timestampDate.toString());
        } catch (ParseException pe) {
            result.append(LINE_SEP).append("Could not interpret timestamp " + timestampString + " using format " + timestampFormat).append(LINE_SEP).append("    ").append(pe.getMessage());
        }

        if (result.length() > 0) {
            throw new IllegalArgumentException(result.toString());
        }
    }

    private int run(String[] args) {
        /*
         *The calling script should pass these command line arguments:
         *
         *arg[0] archive file name and type
         *arg[1] auto-deploy directory spec
         *arg[2] SimpleDateFormat pattern to use in parsing the timestamp string
         *arg[3] timestamp string
         *
         */

        try {
            processArguments(args);

            /*
             *The timestamp handling allows the logic below to identify a marker file (..._deployed,
             *..._undeployed, ..._deployFailed, ..._undeployFailed) that was created after the
             *archive was deposited into (for autodeploy) or removed from (for autoundeploy) the
             *autodeploy directory.  We need to do this to make sure we do not accidentally take
             *action on an old marker file that is still there because the autodeployer has not
             *yet acted on the new file.
             */

            /*
             *For auto-deploy, the archive will have just been copied into the autodeploy directory.
             *For auto-undeploy, the archive will have just been deleted from there.  The file filter
             *below uses both the file name and also a timestamp to make sure it accepts
             *marker files created after the archive itself.
             *
             *Note that the following is both a declaration of the filter and its initialization by
             *invoking its init method.
             */

            FileFilter filter = new FileFilter () {

                private long timestamp;
                private String archiveName = null;

                public boolean accept(File candidateFile) {
                    /*
                     *Make sure the name of the candidate starts with the name of the archive and that
                     *the candidate is no older than the archive file.  Make sure it's one of the marker
                     *file types we're interested in.
                     */
                    String candidateFileSpec = candidateFile.getAbsolutePath();
                    long candidateTimestamp = candidateFile.lastModified();
                    String candidateNameAndType = candidateFileSpec.substring(candidateFileSpec.lastIndexOf(File.separator) + 1);
                    String candidateType = candidateFileSpec.substring(candidateFileSpec.lastIndexOf('.') + 1);

                    boolean answer = (candidateTimestamp > this.timestamp)
                        && (candidateNameAndType.equals(archiveName + AutoDeployConstants.DEPLOYED) ||
                            candidateNameAndType.equals(archiveName + AutoDeployConstants.UNDEPLOYED) ||
                            candidateNameAndType.equals(archiveName + AutoDeployConstants.DEPLOY_FAILED) ||
                            candidateNameAndType.equals(archiveName + AutoDeployConstants.UNDEPLOY_FAILED)
                           );
                    if (DEBUG) {
                        Date candidateTimestampDate = new Date(candidateTimestamp);
                        debug("Result of filtering file " + candidateFileSpec + " with modification date " + candidateTimestampDate.toString() + " : " + answer);
                    }
                    return answer;
                }

                public FileFilter init(String archiveName, long timestamp) {
                    this.archiveName = archiveName;
                    this.timestamp = timestamp;
                    return this;
                }
                }.init(archiveName, timestamp);

            File [] matches = null;

            /*
             *Begin waiting for a new marker file to appear in the autodeploy directory.  Don't wait longer than
             *two minutes (by default) in case there is some problem.
             */
            int iterationCount = 0;
            do {
                debug("Starting polling iteration " + iterationCount + "...");
                Thread.currentThread().sleep(1000);
                /*
                 *List the files that have the same name as the archive but are not the archive itself.
                 *This should mean we get only the marker file(s) for this archive.
                 */
                matches = autodeployDir.listFiles(filter);

            } while ( (matches.length == 0) && (iterationCount++ < ITERATION_LIMIT));

            /*
             *Return 0 if the marker file found ends with _deployed, 1 if the marker ends with
             *_deployFailed, and -1 otherwise.
             */
            if (DEBUG) {
                System.out.println("Matched files:");
                for (int i = 0; i < matches.length; i++) {
                    System.out.println("  " + matches[i].getAbsolutePath());
                }
            }
            String matchFileSpec = matches[0].getAbsolutePath();
            int answer = -1;
            if (matchFileSpec.endsWith(AutoDeployConstants.DEPLOYED) || matchFileSpec.endsWith(AutoDeployConstants.UNDEPLOYED)) {
                answer = 0;
                debug("Found successful marker file: " + matchFileSpec);
            } else if (matchFileSpec.endsWith(AutoDeployConstants.DEPLOY_FAILED) || matchFileSpec.endsWith(AutoDeployConstants.UNDEPLOY_FAILED)) {
                answer = 1;
                debug("Found unsuccessful marker file: " + matchFileSpec);
            } else {
                debug("Found no marker file at all");
            }
            return answer;
        } catch (Throwable thr) {
            System.err.println("Error monitoring autodeployment/autoundeployment");
            thr.printStackTrace();
            return -1;
        }
    }

    private void usage() {
        System.err.println("Usage:");
        System.err.println("    autodeploy.loader.client.AutoDeployMonitor <archive-name> <autodeploy-directory> <SimpleDateFormat-pattern-for-timestamp> <timestamp-value>");
    }

    private void debug(String msg) {
        if (DEBUG) {
            System.out.println(msg);
        }
    }
}
