/*******************************************************************************
 * Copyright (c) 2003, 2004 IBM Corporation 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:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.web.deployables;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jst.j2ee.internal.deployables.J2EEDeployable;
import org.eclipse.jst.j2ee.internal.deployables.LooseArchiveDeployable;
import org.eclipse.jst.j2ee.internal.deployables.LooseArchiveDeployableFactory;
import org.eclipse.jst.j2ee.internal.project.J2EENature;
import org.eclipse.jst.j2ee.internal.web.operations.J2EEWebNatureRuntime;
import org.eclipse.jst.j2ee.internal.web.operations.J2EEWebNatureRuntimeUtilities;
import org.eclipse.jst.server.core.ILooseArchive;
import org.eclipse.jst.server.core.ILooseArchiveSupport;
import org.eclipse.jst.server.core.IWebModule;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IModuleType;
import org.eclipse.wst.web.internal.operation.IBaseWebNature;
import org.eclipse.wst.web.internal.operation.ILibModule;

/**
 * @version 1.0
 * @author
 */
public class J2EEWebDeployable extends J2EEDeployable implements IWebModule, ILooseArchiveSupport, IModuleType {
    protected String contextRoot;

    protected ILooseArchive[] archives;

    protected Map uris = new HashMap();
    

    /**
     * @param aNature
     * @param aFactoryId
     */
    public J2EEWebDeployable(J2EENature aNature, String aFactoryId) {
        super(aNature, aFactoryId);
        this.contextRoot = getUncachedContextRoot();
    }
    
	public String getId() {
		return getProject().getName();
	}

    public String getContextRoot() {
        return this.contextRoot;
    }

    private J2EEWebNatureRuntime getWebNature() {
        return (J2EEWebNatureRuntime) getNature();
    }

    public String getUncachedContextRoot() {
        return getWebNature().getContextRoot();
    }

    public String getJ2EESpecificationVersion() {
        IBaseWebNature baseWebNature = getWebNature();
        if (baseWebNature.isJ2EE()) {
            return ((J2EEWebNatureRuntime) baseWebNature).getJ2EEVersionText();
        }
        return "1.3"; //$NON-NLS-1$
    }

    public String getJSPFileMapping(String jspFile) {
        return null;
    }

    public String getJSPSpecificationVersion() {
        IBaseWebNature baseWebNature = getWebNature();
        if (baseWebNature.isJ2EE()) {
            return ((J2EEWebNatureRuntime) baseWebNature).getJSPLevel();
        }
        return "1.2"; //$NON-NLS-1$
    }

    public String getServletMapping(String className) {
        return null;
    }

    public String getServletSpecificationVersion() {
        IBaseWebNature baseWebNature = getWebNature();
        if (baseWebNature.isJ2EE()) {
            return ((J2EEWebNatureRuntime) baseWebNature).isServlet2_3() ? "2.3" : "2.2"; //$NON-NLS-1$ //$NON-NLS-2$
        }
        return "2.3"; //$NON-NLS-1$
    }

    public boolean isPublishRequired() {
        return false;
    }

    protected LooseArchiveDeployableFactory getLooseArchiveDeployableFactory() {
        /*
         * Iterator factories =
         * Arrays.asList(ServerCore.getModuleFactories()).iterator(); while
         * (factories.hasNext()) { ModuleFactory deployableFactory =
         * (ModuleFactory) factories.next(); ModuleFactoryDelegate
         * deployableFactoryDelegate = deployableFactory.getDelegate(); if
         * (deployableFactoryDelegate instanceof LooseArchiveDeployableFactory)
         * return (LooseArchiveDeployableFactory) deployableFactoryDelegate; }
         */
        return null;
    }

    protected ILooseArchive getArchiveDeployable(IProject aProject, LooseArchiveDeployableFactory fact) {
        return (ILooseArchive) fact.getModuleProject(aProject);
    }

    protected ILibModule[] getLibModules() {
        J2EEWebNatureRuntime j2eeNature = J2EEWebNatureRuntimeUtilities.getJ2EERuntime(this.project);
        if (j2eeNature == null)
            return null;

        ILibModule[] libModules = j2eeNature.getLibModules();

        if (libModules == null || libModules.length == 0)
            return null;
        return libModules;
    }

    public ILooseArchive[] getLooseArchives() {
        return this.archives;
    }

    /*
     * @see com.ibm.etools.server.core.util.DeployableProject#getRootFolder()
     */
    public IPath getRootFolder() {
        J2EEWebNatureRuntime webNature = getWebNature();
        if (webNature != null)
            return getWebNature().getRootPublishableFolder().getProjectRelativePath();
        return null;
    }

    public ILooseArchive[] getUncachedLooseArchives() {
        ILibModule[] libModules = getLibModules();
        if (libModules == null)
            return null;

        LooseArchiveDeployableFactory fact = getLooseArchiveDeployableFactory();
        if (fact == null)
            return null;

        List arcs = new ArrayList(libModules.length);
        for (int i = 0; i < libModules.length; i++) {
            ILibModule libModule = libModules[i];
            IProject proj = libModule.getProject();
            if (proj != null && proj.exists())
                arcs.add(getArchiveDeployable(proj, fact));
        }
        ILooseArchive[] result = new ILooseArchive[arcs.size()];
        arcs.toArray(result);
        return result;
    }

    public String getURI(ILooseArchive jar) {
        try {
            return (String) this.uris.get(jar);
        } catch (Exception e) {
        		// ignore
        }
        return null;
    }

    public String getUncachedURI(ILooseArchive jar) {
        if (!(jar instanceof LooseArchiveDeployable))
            return null;

        LooseArchiveDeployable dep = (LooseArchiveDeployable) jar;
        IProject proj = dep.getProject();
        return getURI(proj);
    }

    protected String getURI(IProject looseJARProject) {
        J2EEWebNatureRuntime j2eeNature = J2EEWebNatureRuntimeUtilities.getJ2EERuntime(this.project);
        if (j2eeNature == null)
            return null;

        ILibModule[] libModules = getLibModules();
        if (libModules == null)
            return null;

        for (int i = 0; i < libModules.length; i++) {
            ILibModule iLibModule = libModules[i];
            if (iLibModule.getProject().equals(looseJARProject))
                return iLibModule.getURI();
        }

        return null;
    }

    public boolean isBinary() {
        return false;
    }

    protected void update() {
        ILooseArchive[] oldArchives = this.archives;
        this.archives = getUncachedLooseArchives();
        if (this.archives == null)
            this.archives = new ILooseArchive[0];
        String oldContextRoot = this.contextRoot;
        this.contextRoot = getUncachedContextRoot();

        boolean changed = false;
        if (oldContextRoot == null && this.contextRoot != null)
            changed = true;
        else if (oldContextRoot != null && !oldContextRoot.equals(this.contextRoot))
            changed = true;

        // fire remove events
        List add = new ArrayList(2);
        addRemovedObjects(add, oldArchives, this.archives);

        // fire add events
        List remove = new ArrayList(2);
        addAddedObjects(remove, oldArchives, this.archives);

        // fire change events
        int size = this.archives.length;
        List change = new ArrayList(size);
        for (int i = 0; i < size; i++) {
            String newURI = getUncachedURI(this.archives[i]);
            String oldURI = getURI(this.archives[i]);

            if (oldURI != null && !oldURI.equals(newURI)) {
                change.add(this.archives[i]);
            }
            this.uris.put(this.archives[i], newURI);
        }

        if (!add.isEmpty() || !remove.isEmpty() || !change.isEmpty() || changed) {
            IModule[] added = new IModule[add.size()];
            add.toArray(added);
            IModule[] changed2 = new IModule[change.size()];
            change.toArray(changed2);
            IModule[] removed = new IModule[remove.size()];
            remove.toArray(removed);
            fireModuleChangeEvent(changed, added, changed2, removed);
        }
    }

    /**
     * Return the objects that have been added between array a and array b.
     * Assumes that there are no null objects in the array.
     */
    protected static void addAddedObjects(List list, Object[] a, Object[] b) {
        if (b == null)
            return;
        else if (a == null) {
            int size = b.length;
            for (int i = 0; i < size; i++)
                list.add(b[i]);
            return;
        }
        int size = b.length;
        for (int i = 0; i < size; i++) {
            Object obj = b[i];
            boolean found = false;
            if (a != null) {
                int size2 = a.length;
                for (int j = 0; !found && j < size2; j++) {
                    if (obj != null && obj.equals(a[j]))
                        found = true;
                }
            }
            if (!found)
                list.add(obj);
        }
    }

    /**
     * Return the objects that have been removed between array a and array b.
     * Assumes that there are no null objects in the array.
     */
    protected static void addRemovedObjects(List list, Object[] a, Object[] b) {
        if (a == null)
            return;
        else if (b == null) {
            int size = a.length;
            for (int i = 0; i < size; i++)
                list.add(a[i]);
            return;
        }
        int size = a.length;
        for (int i = 0; i < size; i++) {
            Object obj = a[i];
            boolean found = false;
            if (b != null) {
                int size2 = b.length;
                for (int j = 0; !found && j < size2; j++) {
                    if (obj != null && obj.equals(b[j]))
                        found = true;
                }
            }
            if (!found)
                list.add(obj);
        }
    }

    public String getType() {
        return "j2ee.web"; //$NON-NLS-1$
    }

    public String getVersion() {
        IBaseWebNature baseWebNature = getWebNature();
        if (baseWebNature.isJ2EE()) {
            return ((J2EEWebNatureRuntime) baseWebNature).getJ2EEVersionText();
        }
        return "1.2"; //$NON-NLS-1$
    }

    /**
     * Returns the child modules of this module.
     * 
     * @return com.ibm.wtp.server.core.model.IModule[]
     */
    public IModule[] getChildModules() {
        List list = new ArrayList();

        if (this.archives != null) {
            int size = this.archives.length;
            for (int i = 0; i < size; i++)
                list.add(this.archives[i]);
        }

        IModule[] children = new IModule[list.size()];
        list.toArray(children);
        return children;
    }

   
    public String getModuleTypeName(){
        return getName();
    }
    
    public String getModuleTypeVersion(){
        return getVersion();
    }


}