/**********************************************************************
 * Copyright (c) 2016, 2022 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.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 Tomcat85PublishModuleVisitor extends TomcatPublishModuleVisitor {

	/**
	 * Instantiate a new Tomcat85PublishModuleVisitor
	 * 
	 * @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 "META-INF/resources" feature should be supported
	 */
	Tomcat85PublishModuleVisitor(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 PreResources 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")) {
				PreResources preResources = (PreResources)context.getResources().createElement("PreResources");
				preResources.setClassName("org.apache.catalina.webresources.FileResourceSet");
				preResources.setBase(jarPath);
				preResources.setWebAppMount("/WEB-INF/lib/" + new File(jarPath).getName());
				preResources.setInternalPath("/");
				preResources.setClassLoaderOnly("false");
			}
			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
		}
	}
}
