/*******************************************************************************
 * Copyright (c) 2010 Angelo Zerr and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation 
 *******************************************************************************/
package org.eclipse.jst.server.jetty.core.internal;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jst.server.core.IWebModule;
import org.eclipse.jst.server.core.internal.ProgressUtil;
import org.eclipse.jst.server.jetty.core.IJettyConfiguration;
import org.eclipse.jst.server.jetty.core.IJettyConfigurationWorkingCopy;
import org.eclipse.jst.server.jetty.core.IJettyServer;
import org.eclipse.jst.server.jetty.core.JettyPlugin;
import org.eclipse.jst.server.jetty.core.WebModule;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.ServerPort;

public abstract class JettyConfiguration implements IJettyConfiguration, IJettyConfigurationWorkingCopy
{

    private IFolder configPath;

    /**
     * JettyConfiguration constructor.
     * 
     * @param path
     *            a path
     */
    public JettyConfiguration(IFolder path)
    {
        super();
        this.configPath = path;
    }

    protected IFolder getFolder()
    {
        return configPath;
    }

    /**
     * Return the port number.
     * 
     * @return int
     */
    public ServerPort getMainPort()
    {
        Collection<ServerPort> serverPorts = getServerPorts();
        for (ServerPort serverPort : serverPorts)
        {
            // Return only an HTTP port from the selected Service
            if (serverPort.getProtocol().toLowerCase().equals("http") && serverPort.getId().indexOf('/') < 0)
                return serverPort;
        }
        return null;
    }

    /**
     * Returns the partial URL applicable to this module.
     * 
     * @param webModule
     *            a web module
     * @return the partial URL
     */
    public String getWebModuleURL(IModule webModule)
    {
        WebModule module = getWebModule(webModule);
        if (module != null)
            return module.getPath();

        IWebModule webModule2 = (IWebModule)webModule.loadAdapter(IWebModule.class,null);
        return "/" + webModule2.getContextRoot();
    }

    /**
     * Returns the given module from the config.
     * 
     * @param module
     *            a web module
     * @return a web module
     */
    public WebModule getWebModule(IModule module)
    {
        if (module == null)
            return null;

        String memento = module.getId();

        List<WebModule> modules = getWebModules();
        int size = modules.size();
        for (int i = 0; i < size; i++)
        {
            WebModule webModule = modules.get(i);
            if (memento.equals(webModule.getMemento()))
            {
                return webModule;
            }
        }
        return null;
    }

    /**
     * Returns the prefix that is used in front of the web module path property. (e.g. "webapps")
     * 
     * @return java.lang.String
     */
    public String getDocBasePrefix()
    {
        return "";
    }

    /**
     * Copies all files from the given directory in the workbench to the given location. Can be overridden by version specific class to modify or enhance what
     * publish does.
     * 
     * @param jettyDir
     *            Destination Jetty directory. Equivalent to catalina.base for Jetty 4.x and up.
     * @param doBackup
     *            Backup existing configuration files (true if not test mode).
     * @param monitor
     *            Progress monitor to use
     * @return result of operation
     */
    public IStatus backupAndPublish(IPath jettyDir, boolean doBackup, IProgressMonitor monitor)
    {
        MultiStatus ms = new MultiStatus(JettyPlugin.PLUGIN_ID,0,Messages.publishConfigurationTask,null);
        if (Trace.isTraceEnabled())
            Trace.trace(Trace.FINER,"Backup and publish");
        monitor = ProgressUtil.getMonitorFor(monitor);

        try
        {
            IPath backup = null;
            if (doBackup)
            {
                // create backup directory
                backup = jettyDir.append("backup");
                if (!backup.toFile().exists())
                    backup.toFile().mkdir();
            }
            backupFolder(getFolder(),jettyDir,backup,ms,monitor);
        }
        catch (Exception e)
        {
            Trace.trace(Trace.SEVERE,"backupAndPublish() error",e);
            IStatus s = new Status(IStatus.ERROR,JettyPlugin.PLUGIN_ID,0,NLS.bind(Messages.errorPublishConfiguration,new String[]
            { e.getLocalizedMessage() }),e);
            ms.add(s);
        }

        monitor.done();
        return ms;
    }

    protected void backupFolder(IFolder folder, IPath confDir, IPath backup, MultiStatus ms, IProgressMonitor monitor) throws CoreException
    {
        IResource[] children = folder.members();
        if (children == null)
            return;

        IResource resource = null;
        int size = children.length;
        monitor.beginTask(Messages.publishConfigurationTask,size * 100);
        for (int i = 0; i < size; i++)
        {
            resource = children[i];
            switch (resource.getType())
            {
                case IResource.FILE:
                    try
                    {
                        IFile file = (IFile)resource;
                        String name = file.getName();
                        monitor.subTask(NLS.bind(Messages.publisherPublishTask,new String[]
                        { name }));
                        if (Trace.isTraceEnabled())
                            Trace.trace(Trace.FINEST,"Publishing " + name);

                        // backup and copy file
                        boolean copy = true;
                        if (backup != null && !(backup.append(name).toFile().exists()))
                        {
                            IStatus status = FileUtil.copyFile(confDir.append(name).toOSString(),backup + File.separator + name);
                            ms.add(status);
                            if (!status.isOK())
                                copy = false;
                        }

                        if (copy)
                        {
                            String destPath = confDir.append(name).toOSString();
                            String destContents = null;
                            String srcContents = null;
                            File dest = new File(destPath);
                            if (dest.exists())
                            {
                                InputStream fis = new FileInputStream(destPath);
                                destContents = FileUtil.getFileContents(fis);
                                if (destContents != null)
                                {
                                    fis = file.getContents();
                                    srcContents = FileUtil.getFileContents(fis);
                                }
                            }
                            if (destContents == null || srcContents == null || !srcContents.equals(destContents))
                            {
                                InputStream in = file.getContents();
                                ms.add(FileUtil.copyFile(in,destPath));
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Trace.trace(Trace.SEVERE,"backupAndPublish() error",e);
                        ms.add(new Status(IStatus.ERROR,JettyPlugin.PLUGIN_ID,0,NLS.bind(Messages.errorPublishConfiguration,new String[]
                        { e.getLocalizedMessage() }),e));
                    }
                    break;
                case IResource.FOLDER:
                    IFolder childFolder = (IFolder)resource;
                    backupFolder(childFolder,confDir.append(childFolder.getName()),(backup != null?backup.append(childFolder.getName()):null),ms,monitor);
                    break;
            }
            monitor.worked(100);
        }
    }

    protected void backupPath(IPath path, IPath confDir, IPath backup, MultiStatus ms, IProgressMonitor monitor)
    {
        File[] files = path.toFile().listFiles();
        if (files == null)
            return;

        int size = files.length;
        monitor.beginTask(Messages.publishConfigurationTask,size * 100);
        for (int i = 0; i < size; i++)
        {
            try
            {
                File file = files[i];
                String name = file.getName();
                monitor.subTask(NLS.bind(Messages.publisherPublishTask,new String[]
                { name }));
                if (Trace.isTraceEnabled())
                    Trace.trace(Trace.FINEST,"Publishing " + name);

                // backup and copy file
                boolean copy = true;
                if (backup != null && !(backup.append(name).toFile().exists()))
                {
                    IStatus status = FileUtil.copyFile(confDir.append(name).toOSString(),backup + File.separator + name);
                    ms.add(status);
                    if (!status.isOK())
                        copy = false;
                }

                if (copy)
                    ms.add(FileUtil.copyFile(file.getAbsolutePath(),confDir.append(name).toOSString()));
            }
            catch (Exception e)
            {
                Trace.trace(Trace.SEVERE,"backupAndPublish() error",e);
                ms.add(new Status(IStatus.ERROR,JettyPlugin.PLUGIN_ID,0,NLS.bind(Messages.errorPublishConfiguration,new String[]
                { e.getLocalizedMessage() }),e));
            }
            monitor.worked(100);
        }
    }

    public IStatus cleanupServer(IPath confDir, IPath installDir, IProgressMonitor monitor)
    {
        // Default implementation assumes nothing to clean
        return Status.OK_STATUS;
    }

    public IStatus localizeConfiguration(IPath confDir, IPath serverDeployDirectory, IJettyServer jettyServer, IProgressMonitor subMonitorFor)
    {
        return Status.OK_STATUS;
    }
}
