package org.eclipse.virgo.nano.deployer.hot;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import org.eclipse.virgo.nano.deployer.core.ApplicationDeployer;
import org.eclipse.virgo.nano.deployer.core.DeploymentException;
import org.eclipse.virgo.nano.deployer.core.DeploymentIdentity;
import org.eclipse.virgo.nano.deployer.core.DeploymentOptions;
import org.eclipse.virgo.nano.deployer.core.FatalDeploymentException;
import org.eclipse.virgo.nano.serviceability.NonNull;
import org.eclipse.virgo.medic.eventlog.EventLogger;
import org.eclipse.virgo.medic.eventlog.LogEvent;
import org.eclipse.virgo.util.io.FileSystemEvent;
import org.eclipse.virgo.util.io.FileSystemListener;
import org.eclipse.virgo.util.io.PathReference;

/**
 * {@link FileSystemListener} that monitors a pickup directory for file system events. When a file is created it is
 * passed to the {@link ApplicationDeployer} for deployment. When a file is modified, it is re-deployed. When a file is
 * deleted, the application is undeployed.
 * <p />
 * The <code>ApplicationDeployer</code> is responsible for recovering the files deployed via this route and is given
 * ownership of these files so that undeploying one of them, e.g. by name and version, will delete the corresponding
 * file in the pickup directory.
 * 
 * <strong>Concurrent Semantics</strong><br />
 * 
 * Threadsafe.
 * 
 */
final class HotDeploymentFileSystemListener implements FileSystemListener {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final EventLogger eventLogger;

    private final ApplicationDeployer deployer;

    /**
     * Creates a new <code>HotDeploymentFileSystemListener</code>.
     * 
     * @param deployer the {@link ApplicationDeployer} to deploy to.
     * @param eventLogger where to log events
     */
    public HotDeploymentFileSystemListener(@NonNull ApplicationDeployer deployer, EventLogger eventLogger) {
        this.deployer = deployer;
        this.eventLogger = eventLogger;
    }

    /**
     * {@inheritDoc}
     * 
     * Reacts to changes in the pickup directory and calls the {@link ApplicationDeployer} as appropriate.
     */
    public void onChange(String path, FileSystemEvent event) {
        String fileName = new PathReference(path).getName();
        this.eventLogger.log(HotDeployerLogEvents.HOT_DEPLOY_PROCESSING_FILE, event, fileName);
        try {
            if (event == FileSystemEvent.CREATED) {
                logger.info("ApplicationDeploying path '{}'.", path);
                deploy(path);
            } else if (event == FileSystemEvent.MODIFIED) {
                logger.info("Redeploying path '{}'.", path);
                deploy(path);
            } else if (event == FileSystemEvent.DELETED) {
                logger.info("ApplicationUndeploying path '{}'.", path);
                undeploy(path);
            } else if (event == FileSystemEvent.INITIAL) {
                logger.info("ApplicationConditionallyDeploying path '{}'.", path);
                deployIfNotDeployed(path, fileName);
            }
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
            determineFailureAndLogMessage(event, fileName, ex);
        }
    }

    /**
     * Determines the {@link LogEvent} that corresponds the {@link FileSystemEvent}.
     */
    private void determineFailureAndLogMessage(FileSystemEvent event, String fileName, Exception ex) {
        switch (event) {
            case CREATED: // fall through
            case INITIAL:
                this.eventLogger.log(HotDeployerLogEvents.HOT_DEPLOY_FAILED, ex, fileName);
                break;
            case MODIFIED:
                this.eventLogger.log(HotDeployerLogEvents.HOT_REDEPLOY_FAILED, ex, fileName);
                break;
            case DELETED:
                this.eventLogger.log(HotDeployerLogEvents.HOT_UNDEPLOY_FAILED, ex, fileName);
                break;
        }
    }

    /**
     * Undeploys the application that corresponds to the supplied source artefact URI.
     * 
     * @param sourceArtefact the source artefact URI string
     * @throws DeploymentException
     */
    private void undeploy(String sourceArtefact) throws DeploymentException {
        DeploymentIdentity deploymentIdentity = getDeploymentIdentity(sourceArtefact);
        if (deploymentIdentity != null) {
            this.deployer.undeploy(deploymentIdentity);
        }
    }

    /**
     * Get the {@link DeploymentIdentity} of the given artefact. Return <code>null</code> if the given artefact is not
     * currently deployed.
     * 
     * @param sourceArtefact the source artefact URI string
     * @return the <code>DeploymentIdentity</code> of the given artefact or <code>null</code>
     */
    private DeploymentIdentity getDeploymentIdentity(String sourceArtefact) {
        return this.deployer.getDeploymentIdentity(getDefinitiveUri(sourceArtefact));
    }

    /**
     * Determine whether or not the given artefact is already deployed. Return <code>true</code> if the given artefact
     * at its file's last modified time is already deployed.
     * 
     * @param sourceArtefact the source artefact URI string
     * @return <code>true</code> if and only if the given artefact at its file's last modified time is already deployed
     */
    private boolean isDeployed(String sourceArtefact) {
        return this.deployer.isDeployed(getDefinitiveUri(sourceArtefact));
    }

    /**
     * Converts a string URI to a URI with a predictable format, particularly in the case where the string URI ends in a
     * file separator.
     * 
     * @param sourceArtefact the URI string
     * @return
     */
    private URI getDefinitiveUri(String sourceArtefact) {
        URI baseUri = new File(sourceArtefact).toURI();
        if (sourceArtefact.endsWith(File.separator) && !baseUri.toString().endsWith("/")) {
            try {
                baseUri = new URI(baseUri.toString() + "/");
            } catch (URISyntaxException e) {
                throw new FatalDeploymentException("Unexpected URI syntax problem.", e);
            }
        }
        return baseUri;
    }

    /**
     * Deploys the application at the supplied PathReference asynchronously.
     * 
     * @param sourceArtefact the source artefact URI string
     * @throws DeploymentException
     */
    private void deploy(String sourceArtefact) throws DeploymentException {
        this.deployer.deploy(getDefinitiveUri(sourceArtefact), new DeploymentOptions(true, true, false));
    }

    /**
     * Deploys the application at the supplied PathReference if it is not already deployed.
     * 
     * @param sourceArtefact the source artefact URI string
     * @param fileName the artefact file name
     * @throws DeploymentException
     */
    private void deployIfNotDeployed(String sourceArtefact, String fileName) throws DeploymentException {
        if (!isDeployed(sourceArtefact)) {
            deploy(sourceArtefact);
        } else {
            this.eventLogger.log(HotDeployerLogEvents.HOT_DEPLOY_SKIPPED, fileName);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "Hot Deploy Listener";
    }
}
