/*********************************************************************
 * Copyright (c) 2009, 2010 SpringSource, a division of VMware, Inc.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
**********************************************************************/

package org.eclipse.virgo.ide.runtime.internal.core;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeoutException;

import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.virgo.ide.facet.core.FacetCorePlugin;
import org.eclipse.virgo.ide.facet.core.FacetUtils;
import org.eclipse.virgo.ide.manifest.core.BundleManifestCorePlugin;
import org.eclipse.virgo.ide.runtime.core.IServerBehaviour;
import org.eclipse.virgo.ide.runtime.core.IServerDeployer;
import org.eclipse.virgo.ide.runtime.core.ServerUtils;
import org.eclipse.virgo.ide.runtime.internal.core.command.IServerCommand;
import org.eclipse.virgo.ide.runtime.internal.core.utils.StatusUtil;
import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.model.IModuleFile;

/**
 * Deployer helper that hides the JMX-based communication with a running dm Server.
 *
 * @author Christian Dupuis
 * @since 2.0.0
 */
public class DefaultServerDeployer implements IServerDeployer {

    private final IServerBehaviour behaviour;

    public DefaultServerDeployer(IServerBehaviour behaviour) {
        this.behaviour = behaviour;
    }

    /**
     * {@inheritDoc}
     */
    public void deploy(IModule... modules) {
        List<IModule> orderedModules = Arrays.asList(modules);

        // make sure we honor the user configured order
        final List<String> orderedArtefacts = getArtefactOrder();

        // sort the modules according the order defined in the server
        // configuration
        Collections.sort(orderedModules, new Comparator<IModule>() {

            public int compare(IModule o1, IModule o2) {
                Integer m1 = orderedArtefacts.contains(o1.getId()) ? orderedArtefacts.indexOf(o1.getId()) : Integer.MAX_VALUE;
                Integer m2 = orderedArtefacts.contains(o2.getId()) ? orderedArtefacts.indexOf(o2.getId()) : Integer.MAX_VALUE;
                return m1.compareTo(m2);
            }
        });

        for (IModule module : orderedModules) {
            DeploymentIdentity identity = executeDeployerCommand(getServerDeployCommand(module));
            if (this.behaviour instanceof ServerBehaviour) {
                ((ServerBehaviour) this.behaviour).tail(identity);
            }
            this.behaviour.onModulePublishStateChange(new IModule[] { module }, IServer.PUBLISH_STATE_NONE);
            // if (identity != null) {
            // behaviour.onModuleStateChange(new IModule[] { module },
            // IServer.STATE_STARTED);
            // }
            // else {
            // behaviour.onModuleStateChange(new IModule[] { module },
            // IServer.STATE_STOPPED);
            // }
        }
    }

    /**
     * {@inheritDoc}
     */
    public Boolean ping() throws IOException, TimeoutException {
        return getServerPingCommand().execute();
    }

    /**
     * {@inheritDoc}
     */
    public void redeploy(IModule module) {

        DeploymentIdentity identity = this.behaviour.getDeploymentIdentities().get(module.getId());
        if (identity == null) {
            identity = executeDeployerCommand(getServerDeployCommand(module));
        } else {
            // Special handling for pars with nested bundles to determine if
            // only one of the bundles
            // refreshing
            if (FacetUtils.isParProject(module.getProject())) {

                Set<String> bundleSymbolicNames = new LinkedHashSet<String>();
                IModule[] children = getModuleChildren(module);
                // If only one module has actual changes; emit a bundle refresh
                // only
                for (IModule child : children) {
                    int state = getModuleState(module, child);
                    if (state != IServer.PUBLISH_STATE_NONE) {
                        if (FacetUtils.isBundleProject(child.getProject())) {
                            BundleManifest manifest = BundleManifestCorePlugin.getBundleManifestManager().getBundleManifest(
                                JavaCore.create(child.getProject()));
                            if (manifest != null && manifest.getBundleSymbolicName() != null) {
                                bundleSymbolicNames.add(manifest.getBundleSymbolicName().getSymbolicName());
                            }
                        }
                    }
                }

                // Only one changed bundle found -> update single one
                if (bundleSymbolicNames.size() == 1) {
                    executeDeployerCommand(getServerRefreshCommand(module, bundleSymbolicNames.iterator().next()));
                } else {
                    identity = executeDeployerCommand(getServerDeployCommand(module));
                }
            } else {
                identity = executeDeployerCommand(getServerRedeployCommand(module));
            }
        }

        // if (identity != null) {
        // behaviour.onModuleStateChange(new IModule[] { module },
        // IServer.STATE_STARTED);
        // }
        // else {
        // behaviour.onModuleStateChange(new IModule[] { module },
        // IServer.STATE_STOPPED);
        // }

    }

    /**
     * {@inheritDoc}
     */
    protected IModule[] getModuleChildren(IModule module) {
        return ServerUtils.getServer(this.behaviour).getChildModules(new IModule[] { module });
    }

    /**
     * {@inheritDoc}
     */
    protected int getModuleState(IModule module, IModule child) {
        return ServerUtils.getServer(this.behaviour).getServer().getModulePublishState(new IModule[] { module, child });
    }

    /**
     * {@inheritDoc}
     */
    protected List<String> getArtefactOrder() {
        return ServerUtils.getServer(this.behaviour).getConfiguration().getArtefactOrder();
    }

    /**
     * {@inheritDoc}
     */
    public void refresh(IModule parModule, IModule... modules) {
        for (IModule module : modules) {
            BundleManifest manifest = BundleManifestCorePlugin.getBundleManifestManager().getBundleManifest(JavaCore.create(module.getProject()));
            if (manifest != null && manifest.getBundleSymbolicName() != null) {
                executeDeployerCommand(getServerRefreshCommand(parModule, manifest.getBundleSymbolicName().getSymbolicName()));
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void refreshStatic(IModule module, IModuleFile file) {

        DeploymentIdentity identity = this.behaviour.getDeploymentIdentities().get(module.getId());
        if (identity != null) {

            if (FacetUtils.isParProject(module.getProject()) || FacetUtils.isPlanProject(module.getProject())) {
                IFile f = file.getAdapter(IFile.class);
                if (f != null) {
                    if (FacetUtils.isBundleProject(f.getProject()) || FacetUtils.hasProjectFacet(f.getProject(), FacetCorePlugin.WEB_FACET_ID)) {
                        BundleManifest manifest = BundleManifestCorePlugin.getBundleManifestManager().getBundleManifest(
                            JavaCore.create(f.getProject()));
                        String symbolicName = null;
                        if (manifest != null && manifest.getBundleSymbolicName() != null) {
                            symbolicName = manifest.getBundleSymbolicName().getSymbolicName();
                        } else {
                            symbolicName = f.getProject().getName();
                        }
                        String projectPath = f.getProject().getName();
                        String path = file.getModuleRelativePath().toString();

                        // add 5 for .jar or .war + / (see
                        // ServerModuleDelegate#members())
                        if (path.length() > projectPath.length() + 5) {
                            path = path.substring(projectPath.length() + 5);
                            executeDeployerCommand(getServerUpdateCommand(module, file, identity, symbolicName, path));
                        } else {
                            executeDeployerCommand(getServerUpdateCommand(module, file, identity, symbolicName, ""));
                        }
                    }
                }
            } else {
                executeDeployerCommand(getServerUpdateCommand(module, file, identity, null, file.getModuleRelativePath().toString()));
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void shutdown() throws IOException, TimeoutException {
        getServerShutdownCommand().execute();
    }

    /**
     * {@inheritDoc}
     */
    public void undeploy(IModule... modules) {
        for (IModule module : modules) {
            executeDeployerCommand(getServerUndeployCommand(module));
            // behaviour.onModuleStateChange(new IModule[] { module },
            // IServer.STATE_STOPPED);
        }
    }

    protected <T> T executeDeployerCommand(IServerCommand<T> serverCommand) {
        try {
            return serverCommand.execute();
        } catch (IOException e) {
            StatusUtil.error("Failed execution of deployer command " + serverCommand, e);
        } catch (TimeoutException e) {
            // StatusUtil.error("Failed execution of deployer command " + serverCommand, e, StatusManager.SHOW);
        }
        return null;
    }

    protected IServerCommand<DeploymentIdentity> getServerDeployCommand(IModule module) {
        return this.behaviour.getVersionHandler().getServerDeployCommand(this.behaviour, module);
    }

    protected IServerCommand<DeploymentIdentity> getServerRedeployCommand(IModule module) {
        return this.behaviour.getVersionHandler().getServerRedeployCommand(this.behaviour, module);
    }

    protected IServerCommand<Boolean> getServerPingCommand() {
        return this.behaviour.getVersionHandler().getServerPingCommand(this.behaviour);
    }

    protected IServerCommand<Void> getServerRefreshCommand(IModule module, String bundleSymbolicName) {
        return this.behaviour.getVersionHandler().getServerRefreshCommand(this.behaviour, module, bundleSymbolicName);
    }

    protected IServerCommand<Void> getServerShutdownCommand() {
        return this.behaviour.getVersionHandler().getServerShutdownCommand(this.behaviour);
    }

    protected IServerCommand<Void> getServerUndeployCommand(IModule module) {
        return this.behaviour.getVersionHandler().getServerUndeployCommand(this.behaviour, module);
    }

    protected IServerCommand<Void> getServerUpdateCommand(IModule module, IModuleFile moduleFile, DeploymentIdentity identity,
        String bundleSymbolicName, String targetPath) {
        return this.behaviour.getVersionHandler().getServerUpdateCommand(this.behaviour, module, moduleFile, identity, bundleSymbolicName,
            targetPath);
    }

}
