/*******************************************************************************
 * Copyright (c) 2000, 2015 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.help.internal.webapp.servlet;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.core.runtime.Platform;
import org.eclipse.help.internal.base.BaseHelpSystem;
import org.eclipse.help.internal.base.HelpApplication;
import org.eclipse.help.internal.base.HelpDisplay;
import org.eclipse.help.internal.webapp.data.UrlUtil;
import org.osgi.framework.Bundle;

/**
 * Servlet to control Eclipse helpApplication from standalone application.
 * Accepts the following parameters: command=displayHelp | shutdown
 * | install | update | enable | disable | uninstall | search | listFeatures
 * | addSite | removeSite | apply.  
 * href - may be provided if comand==displayHelp.
 * featureId, version, from, to, verifyOnly may be provided for update commands
 */
public class ControlServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	public static final String UPDATE_PLUGIN_ID = "org.eclipse.update.core"; //$NON-NLS-1$

	public static final String CMD_DISPLAYHELP = "displayHelp"; //$NON-NLS-1$
	
	public static final String CMD_DISPLAYHELPWINDOW = "displayHelpWindow"; //$NON-NLS-1$

	public static final String CMD_SHUTDOWN = "shutdown"; //$NON-NLS-1$

	public static final String CMD_INSTALL = "install"; //$NON-NLS-1$

	public static final String CMD_UPDATE = "update"; //$NON-NLS-1$

	public static final String CMD_ENABLE = "enable"; //$NON-NLS-1$

	public static final String CMD_DISABLE = "disable"; //$NON-NLS-1$

	public static final String CMD_UNINSTALL = "uninstall"; //$NON-NLS-1$

	public static final String CMD_SEARCH = "search"; //$NON-NLS-1$

	public static final String CMD_LIST = "listFeatures"; //$NON-NLS-1$

	public static final String CMD_ADDSITE = "addSite"; //$NON-NLS-1$

	public static final String CMD_APPLY = "apply"; //$NON-NLS-1$

	public static final String CMD_REMOVESITE = "removeSite"; //$NON-NLS-1$

	public static final String PACKAGE_PREFIX = "org.eclipse.update.standalone."; //$NON-NLS-1$

	public static final String CLASS_INSTALL = PACKAGE_PREFIX
			+ "InstallCommand"; //$NON-NLS-1$

	public static final String CLASS_UPDATE = PACKAGE_PREFIX + "UpdateCommand"; //$NON-NLS-1$

	public static final String CLASS_ENABLE = PACKAGE_PREFIX + "EnableCommand"; //$NON-NLS-1$

	public static final String CLASS_DISABLE = PACKAGE_PREFIX
			+ "DisableCommand"; //$NON-NLS-1$

	public static final String CLASS_UNINSTALL = PACKAGE_PREFIX
			+ "UninstallCommand"; //$NON-NLS-1$

	public static final String CLASS_SEARCH = PACKAGE_PREFIX + "SearchCommand"; //$NON-NLS-1$

	public static final String CLASS_LIST = PACKAGE_PREFIX
			+ "ListFeaturesCommand"; //$NON-NLS-1$

	public static final String CLASS_ADDSITE = PACKAGE_PREFIX
			+ "AddSiteCommand"; //$NON-NLS-1$

	public static final String CLASS_REMOVESITE = PACKAGE_PREFIX
			+ "RemoveSiteCommand"; //$NON-NLS-1$

	public static final String PARAM_FEATUREID = "featureId"; //$NON-NLS-1$

	public static final String PARAM_VERSION = "version"; //$NON-NLS-1$

	public static final String PARAM_FROM = "from"; //$NON-NLS-1$

	public static final String PARAM_TO = "to"; //$NON-NLS-1$

	public static final String PARAM_VERIFYONLY = "verifyOnly"; //$NON-NLS-1$

	private HelpDisplay helpDisplay = null;

	private boolean shuttingDown = false;

	/**
	 * Called by the servlet container to indicate to a servlet that the servlet
	 * is being placed into service.
	 */
	@Override
	public void init() throws ServletException {
		super.init();
		if (BaseHelpSystem.getMode() == BaseHelpSystem.MODE_STANDALONE) {
			helpDisplay = BaseHelpSystem.getHelpDisplay();
		}
	}

	/**
	 * Called by the server (via the <code>service</code> method) to allow a
	 * servlet to handle a GET request.
	 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		processRequest(req, resp);
	}

	/**
	 * Called by the server (via the <code>service</code> method) to allow a
	 * servlet to handle a POST request.
	 */
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		processRequest(req, resp);
	}

	private void processRequest(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		req.setCharacterEncoding("UTF-8"); //$NON-NLS-1$

		// for HTTP 1.1
		resp.setHeader("Cache-Control", "no-cache"); //$NON-NLS-1$ //$NON-NLS-2$
		// for HTTP 1.0
		resp.setHeader("Pragma", "no-cache"); //$NON-NLS-1$ //$NON-NLS-2$
		resp.setDateHeader("Expires", 0); //$NON-NLS-1$
		//prevents caching at the proxy server

		if (!UrlUtil.isLocalRequest(req)) {
			// do not allow remote clients to execute this servlet
			return;
		}
		if (!"/help".equals(req.getContextPath()) //$NON-NLS-1$
				|| !"/control".equals(req.getServletPath())) { //$NON-NLS-1$
			// do not allow arbitrary URLs to execute this servlet
			resp.sendError(HttpServletResponse.SC_FORBIDDEN, ""); //$NON-NLS-1$
			return;
		}

		if (shuttingDown) {
			return;
		}

		String command = req.getParameter("command"); //$NON-NLS-1$
		if (command == null) {
			// this should never happen and is invisible to the user
			resp.getWriter().print("No command."); //$NON-NLS-1$
			return;
		}

		if (CMD_SHUTDOWN.equalsIgnoreCase(command)) {
			shutdown();
		} else if (CMD_DISPLAYHELP.equalsIgnoreCase(command)) {
			if (BaseHelpSystem.getMode() == BaseHelpSystem.MODE_STANDALONE) {
				displayHelp(req);
			}
		} else if (CMD_DISPLAYHELPWINDOW.equalsIgnoreCase(command)) {
			if (BaseHelpSystem.getMode() == BaseHelpSystem.MODE_STANDALONE) {
				displayHelp(req);
				HelpApplication.setShutdownOnClose(true);
			}
		} else if (CMD_INSTALL.equalsIgnoreCase(command)
				|| CMD_ENABLE.equalsIgnoreCase(command)
				|| CMD_UPDATE.equalsIgnoreCase(command)
				|| CMD_DISABLE.equalsIgnoreCase(command)
				|| CMD_UNINSTALL.equalsIgnoreCase(command)
				|| CMD_SEARCH.equalsIgnoreCase(command)
				|| CMD_LIST.equalsIgnoreCase(command)
				|| CMD_ADDSITE.equalsIgnoreCase(command)
				|| CMD_REMOVESITE.equalsIgnoreCase(command)
				|| CMD_APPLY.equalsIgnoreCase(command)) {
			updateDocs(command, req);
		} else {
			// this should never happen and is invisible to the user
			resp.getWriter().print("Unrecognized command."); //$NON-NLS-1$
		}
	}

	private void updateDocs(String command, HttpServletRequest req) {
		Bundle bundle = Platform.getBundle(UPDATE_PLUGIN_ID);
		if (bundle == null) {
			// no update plugin present
			return;
		}
		try {
			String className = getStandaloneClassName(command);
			if (className == null) {
				System.out.println("No class name for command " + command); //$NON-NLS-1$
				return;
			}
			Class<?> c = bundle.loadClass(className);
			if (c == null) {
				System.out.println("No class for command " + command); //$NON-NLS-1$
				return;
			}
			Class<?>[] parameterTypes = getParameterTypes(className);
			Constructor<?> constr = c.getConstructor(parameterTypes);
			if (constr == null) {
				System.out.println("No expected constructor for command " //$NON-NLS-1$
						+ command);
				return;
			}
			Method m;
			if (!CMD_APPLY.equalsIgnoreCase(command)) {
				m = c.getMethod("run", new Class[]{}); //$NON-NLS-1$
			} else {
				m = c.getMethod("applyChangesNow", new Class[]{}); //$NON-NLS-1$
			}
			Object[] initargs = getInitArgs(className, req);
			Object o = constr.newInstance(initargs);
			Object ret = m.invoke(o, new Object[]{});
			if (!CMD_APPLY.equalsIgnoreCase(command) &&((Boolean)ret).equals(Boolean.FALSE)){
				System.out.println("Command not executed."); //$NON-NLS-1$
			} else {
				System.out.println("Command executed."); //$NON-NLS-1$
			}
		} catch (Exception e) {
			Throwable t = e;
			if (e instanceof InvocationTargetException) {
				t = ((InvocationTargetException) e).getTargetException();
			}
			System.out.println(t.getLocalizedMessage());
			//t.printStackTrace();
		}
	}

	private String getStandaloneClassName(String command) {
		if (CMD_INSTALL.equalsIgnoreCase(command))
			return CLASS_INSTALL;
		else if (CMD_UPDATE.equalsIgnoreCase(command))
			return CLASS_UPDATE;
		else if (CMD_ENABLE.equalsIgnoreCase(command))
			return CLASS_ENABLE;
		else if (CMD_DISABLE.equalsIgnoreCase(command))
			return CLASS_DISABLE;
		else if (CMD_UNINSTALL.equalsIgnoreCase(command))
			return CLASS_UNINSTALL;
		else if (CMD_SEARCH.equalsIgnoreCase(command))
			return CLASS_SEARCH;
		else if (CMD_LIST.equalsIgnoreCase(command)
				|| CMD_APPLY.equalsIgnoreCase(command))
			return CLASS_LIST;
		else if (CMD_ADDSITE.equalsIgnoreCase(command))
			return CLASS_ADDSITE;
		else if (CMD_REMOVESITE.equalsIgnoreCase(command))
			return CLASS_REMOVESITE;
		else
			return null;
	}

	private Class<?>[] getParameterTypes(String className) {
		if (CLASS_INSTALL.equals(className))
			return new Class[]{String.class, String.class, String.class,
					String.class, String.class};
		else if (CLASS_UPDATE.equals(className))
			return new Class[]{String.class, String.class, String.class};
		else if (CLASS_ENABLE.equals(className)
				|| CLASS_DISABLE.equals(className)
				|| CLASS_UNINSTALL.equals(className))
			return new Class[]{String.class, String.class, String.class,
					String.class};
		else
			return new Class[]{String.class};
	}

	private Object[] getInitArgs(String className, HttpServletRequest req) {
		String featureId = req.getParameter(PARAM_FEATUREID); 
		String version = req.getParameter(PARAM_VERSION); 
		String fromSite = req.getParameter(PARAM_FROM); 
		String toSite = req.getParameter(PARAM_TO); 
		String verifyOnly = req.getParameter(PARAM_VERIFYONLY); 
		if (CLASS_INSTALL.equals(className))
			return new Object[]{featureId, version, fromSite, toSite,
					verifyOnly};
		else if (CLASS_UPDATE.equals(className))
			return new Object[]{featureId, version, verifyOnly};
		else if (CLASS_ENABLE.equals(className)
				|| CLASS_DISABLE.equals(className)
				|| CLASS_UNINSTALL.equals(className))
			return new Object[]{featureId, version, toSite, verifyOnly};
		else if (CLASS_REMOVESITE.equals(className))
			return new Object[]{toSite};
		else
			return new Object[]{fromSite};
	}

	/**
	 * Shuts-down Eclipse helpApplication.
	 */
	private void shutdown() {
		shuttingDown = true;
		HelpApplication.stopHelp();
	}

	/**
	 * Displays help.
	 * 
	 * @param req
	 *            HttpServletRequest that might contain href parameter, which is
	 *            the resource to display
	 */
	private void displayHelp(HttpServletRequest req) {
		String href = req.getParameter("href"); //$NON-NLS-1$
		if (href != null) {
			helpDisplay.displayHelpResource(href, false);
		} else {
			helpDisplay.displayHelp(false);
		}
	}
}
