/**********************************************************************
 * Copyright (c) 2016 SAS Institute and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *    SAS Institute - Initial API and implementation
 **********************************************************************/
package org.eclipse.jst.server.tomcat.core.internal;

import java.io.File;
import java.io.FileFilter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jst.server.tomcat.core.internal.xml.server40.Context;
import org.eclipse.jst.server.tomcat.core.internal.xml.server40.JarResources;
import org.eclipse.jst.server.tomcat.core.internal.xml.server40.PostResources;
import org.eclipse.jst.server.tomcat.core.internal.xml.server40.PreResources;
import org.eclipse.jst.server.tomcat.core.internal.xml.server40.ServerInstance;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.ServerUtil;

public class Tomcat90PublishModuleVisitor extends TomcatPublishModuleVisitor {

	/**
	 * Instantiate a new Tomcat90PublishModuleVisitor
	 * 
	 * @param baseDir catalina base path
	 * @param tomcatVersion tomcat version
	 * @param serverInstance ServerInstance containing server.xml contents
	 * @param sharedLoader string value for shared.loader catalina configuration property
	 * @param enableMetaInfResources flag to indicate if Servlet 3.0 or greater "META-INF/resources" feature should be supported
	 */
	Tomcat90PublishModuleVisitor(IPath baseDir, String tomcatVersion, ServerInstance serverInstance, String sharedLoader, boolean enableMetaInfResources) {
		super(baseDir, tomcatVersion, serverInstance, sharedLoader, enableMetaInfResources);
	}

    /**
     * {@inheritDoc}
     */
	@Override
    public void endVisitWebComponent(IVirtualComponent component)
            throws CoreException {

        // track context changes, don't rewrite if not needed
        boolean dirty = false;

        IModule module = ServerUtil.getModule(component.getProject());

        // we need this for the user-specified context path
        Context context = findContext(module);
        if (context == null) {
        	String name = module != null ? module.getName() : component.getName();
    		Trace.trace(Trace.SEVERE, "Could not find context for module " + name);
    		throw new CoreException(new Status(IStatus.ERROR, TomcatPlugin.PLUGIN_ID, 0,
    				NLS.bind(Messages.errorPublishContextNotFound, name), null));
        }

		dirty = includeProjectContextXml(component, context);
		dirty = updateDocBaseAndPath(component, context);

		// Add WEB-INF/classes elements as PreResources
		for (Iterator iterator = virtualClassClasspathElements.iterator();
				iterator.hasNext();) {
			Object virtualClassClasspathElement = iterator.next();
			PreResources preResources = (PreResources)context.getResources().createElement("PreResources");
			preResources.setClassName("org.apache.catalina.webresources.DirResourceSet");
			preResources.setBase(virtualClassClasspathElement.toString());
			preResources.setWebAppMount("/WEB-INF/classes");
			preResources.setInternalPath("/");
			preResources.setClassLoaderOnly("false");
		}
		virtualClassClasspathElements.clear();

		// Add Jars as JarResources if a jar, or as PostResources if a utility project
		for (Iterator iterator = virtualJarClasspathElements.iterator();
				iterator.hasNext();) {
			Object virtualJarClassClasspathElement = iterator.next();
			String jarPath = virtualJarClassClasspathElement.toString();
			if (jarPath.endsWith(".jar")) {
				JarResources jarResources = (JarResources)context.getResources().createElement("JarResources");
				jarResources.setClassName("org.apache.catalina.webresources.JarResourceSet");
				jarResources.setBase(jarPath);
				jarResources.setWebAppMount("/WEB-INF/classes");
				jarResources.setInternalPath("/");
				jarResources.setClassLoaderOnly("true");
			}
			else {
				PostResources postResources = (PostResources)context.getResources().createElement("PostResources");
				postResources.setClassName("org.apache.catalina.webresources.DirResourceSet");
				postResources.setBase(jarPath);
				postResources.setWebAppMount("/WEB-INF/classes");
				postResources.setInternalPath("/");
				postResources.setClassLoaderOnly("false");
				// Map META-INF tld files to WEB-INF
				File metaInfDir = new File(jarPath + "/META-INF");
				if (metaInfDir.isDirectory() && metaInfDir.exists()) {
					// Map META-INF directory directly to /META-INF
					postResources = (PostResources)context.getResources().createElement("PostResources");
					postResources.setClassName("org.apache.catalina.webresources.DirResourceSet");
					postResources.setBase(metaInfDir.getPath());
					postResources.setWebAppMount("/META-INF");
					postResources.setInternalPath("/");
					postResources.setClassLoaderOnly("false");

					File [] tldFiles = metaInfDir.listFiles(new FileFilter() {
							public boolean accept(File file) {
								if (file.isFile() && file.getName().endsWith(".tld")) {
									return true;
								}
								return false;
							}
						});
					for (int i = 0; i < tldFiles.length; i++) {
						postResources = (PostResources)context.getResources().createElement("PostResources");
						postResources.setClassName("org.apache.catalina.webresources.FileResourceSet");
						postResources.setBase(tldFiles[0].getPath());
						postResources.setWebAppMount("/WEB-INF/" + tldFiles[0].getName());
						postResources.setInternalPath("/");
						postResources.setClassLoaderOnly("false");
					}
				}
			}
		}
		virtualJarClasspathElements.clear();

		Set<String> rtPathsProcessed = new HashSet<String>();
		Set<String> locationsIncluded = new HashSet<String>();
		String docBase = context.getDocBase();
		locationsIncluded.add(docBase);
		Map<String, String> retryLocations = new HashMap<String, String>();
		IVirtualResource [] virtualResources = component.getRootFolder().getResources("");
		// Loop over the module's resources
		for (int i = 0; i < virtualResources.length; i++) {
			String rtPath = virtualResources[i].getRuntimePath().toString();
			// Note: The virtual resources returned only know their runtime path.
			// Asking for the project path for this resource performs a lookup
			// that will only return the path for the first mapping for the
			// runtime path.  Thus use of getUnderlyingResources() is necessary.
			// However, this returns matching resources from all mappings so
			// we have to try to keep only those that are mapped directly
			// to the runtime path in the .components file.

			// If this runtime path has not yet been processed
			if (!rtPathsProcessed.contains(rtPath)) {
				// If not a Java related resource
				if (!"/WEB-INF/classes".equals(rtPath)) {
					// Get all resources for this runtime path
					IResource[] underlyingResources = virtualResources[i].getUnderlyingResources();
					// If resource is mapped to "/", then we know it corresponds directly
					// to a mapping in the .components file
					if ("/".equals(rtPath)) {
						for (int j = 0; j < underlyingResources.length; j++) {
							IPath resLoc = underlyingResources[j].getLocation();
							String location = resLoc.toOSString();
							if (!location.equals(docBase)) {
								PreResources preResources = (PreResources)context.getResources().createElement("PreResources");
								preResources.setClassName("org.apache.catalina.webresources.DirResourceSet");
								preResources.setBase(location);
								preResources.setWebAppMount("/");
								preResources.setInternalPath("/");
								preResources.setClassLoaderOnly("false");
								// Add to the set of locations included
								locationsIncluded.add(location);
							}
						}
					}
					// Else this runtime path is something other than "/"
					else {
						int idx = rtPath.lastIndexOf('/');
						// If a "normal" runtime path
						if (idx >= 0) {
							// Get the name of the last segment in the runtime path
							String lastSegment = rtPath.substring(idx + 1);
							// Check the underlying resources to determine which correspond to mappings
							for (int j = 0; j < underlyingResources.length; j++) {
								IPath resLoc = underlyingResources[j].getLocation();
								String location = resLoc.toOSString();
								// If the last segment of the runtime path doesn't match the
								// the last segment of the location, then we have a direct mapping
								// from the .contents file.
								if (!lastSegment.equals(resLoc.lastSegment())) {
									PreResources preResources = (PreResources)context.getResources().createElement("PreResources");
									preResources.setClassName("org.apache.catalina.webresources.DirResourceSet");
									preResources.setBase(location);
									preResources.setWebAppMount(rtPath);
									preResources.setInternalPath("/");
									preResources.setClassLoaderOnly("false");
									// Add to the set of locations included
									locationsIncluded.add(location);
								}
								// Else last segment of runtime path did match the last segment
								// of the location.  We likely have a subfolder of a mapping
								// that matches a portion of the runtime path.
								else {
									// Since we can't be sure, save so it can be check again later
									retryLocations.put(location, rtPath);
								}
							}
						}
					}
				}
				// Add the runtime path to those already processed
				rtPathsProcessed.add(rtPath);
			}
		}
		// If there are locations to retry, add any not yet included in extra paths setting
		if (!retryLocations.isEmpty()) {
			// Remove retry locations already included in the extra paths
			for (Iterator iterator = retryLocations.keySet().iterator(); iterator.hasNext();) {
				String location = (String)iterator.next();
				for (Iterator iterator2 = locationsIncluded.iterator(); iterator2.hasNext();) {
					String includedLocation = (String)iterator2.next();
					if (location.equals(includedLocation) || location.startsWith(includedLocation + File.separator)) {
						iterator.remove();
						break;
					}
				}
			}
			// If any entries are left, include them in the extra paths
			if (!retryLocations.isEmpty()) {
				for (Iterator iterator = retryLocations.entrySet().iterator(); iterator.hasNext();) {
					Map.Entry entry = (Map.Entry)iterator.next();
					String location = (String)entry.getKey();
					String rtPath = (String)entry.getValue();
					PreResources preResources = (PreResources)context.getResources().createElement("PreResources");
					preResources.setClassName("org.apache.catalina.webresources.DirResourceSet");
					preResources.setBase(location);
					preResources.setWebAppMount(rtPath);
					preResources.setInternalPath("/");
					preResources.setClassLoaderOnly("false");
				}
			}
		}
		if (!virtualDependentResources.isEmpty()) {
			for (Map.Entry<String, List<String>> entry : virtualDependentResources.entrySet()) {
				String rtPath = entry.getKey();
				List<String> locations = entry.getValue();
				for (String location : locations) {
					PostResources postResources = (PostResources)context.getResources().createElement("PostResources");
					postResources.setClassName("org.apache.catalina.webresources.DirResourceSet");
					postResources.setBase(location);
					postResources.setWebAppMount(rtPath.length() > 0 ? rtPath : "/");
					postResources.setInternalPath("/");
					postResources.setClassLoaderOnly("false");
				}
			}
		}
		virtualDependentResources.clear();

		if (dirty) {
			//TODO If writing to separate context XML files, save "dirty" status for later use
		}
	}
}
