//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.publishing.services;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.net.proxy.IProxyData;
import org.eclipse.core.net.proxy.IProxyService;
import org.eclipse.core.runtime.Platform;
import org.eclipse.epf.common.utils.Timer;
import org.eclipse.epf.library.layout.DefaultContentValidator;
import org.eclipse.epf.library.layout.LinkInfo;
import org.eclipse.epf.library.layout.util.XmlElement;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.publishing.PublishingPlugin;
import org.eclipse.epf.publishing.PublishingResources;
import org.eclipse.epf.publishing.util.http.HttpResponse;
import org.eclipse.epf.publishing.util.http.HttpUtil;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

import com.ibm.icu.util.Calendar;

/**
 * content validator used for publishing. This class will be responsible for
 * validating the content to be published, fixing problems such as links in the
 * content, and logging information about missing elements, missing resources,
 * etc.
 * 
 * @author Jinhua Xi
 * @since 1.0
 * 
 */
public class PublishingContentValidator extends DefaultContentValidator {

	private boolean debug = PublishingPlugin.getDefault().isDebugging();

	// private boolean showExtraInfoForDescriptors = false;
	// private boolean showRelatedDescriptors = false;

	protected PublishHTMLOptions options = null;

	class InvalidExternalLinkInfo {
		public MethodElement owner;

		public String url;

		public String message;

		public InvalidExternalLinkInfo(MethodElement owner, String url,
				String message) {
			this.owner = owner;
			this.url = url;
			this.message = message;
		}
	}

	class MissingReference {
		public MethodElement owner;

		public MethodElement refElement;

		public String guid;

		public String linkedText;

		public MissingReference(MethodElement owner, MethodElement refElement) {
			this.owner = owner;
			this.refElement = refElement;
		}

		public MissingReference(MethodElement owner, String guid,
				String linkedText) {
			this.owner = owner;
			this.guid = guid;
			this.linkedText = linkedText;
		}
	}

	class MissingResource {
		public MethodElement owner;

		public File resourceFile;

		public String url;

		public MissingResource(MethodElement owner, File resourceFile,
				String url) {
			this.owner = owner;
			this.resourceFile = resourceFile;
			this.url = url;
		}
	}

	static final String LOGS_FOLDER = "logs"; //$NON-NLS-1$

	static final String ERROR_LOG_FILENAME = "error.log"; //$NON-NLS-1$

	static final String WARNING_LOG_FILENAME = "warning.log"; //$NON-NLS-1$

	static final String INFO_LOG_FILENAME = "info.log"; //$NON-NLS-1$

	static final String CORE_NET_BUNDLE = "org.eclipse.core.net";

	protected File logPath;

	protected boolean validateExternalLinks = false;

	protected List invalidExternalLinks = new ArrayList();

	// cache the valided external links to avoid multiple checking
	protected List validatedExternalLinks = new ArrayList();

	protected List missingReferences = new ArrayList();

	protected List missingResources = new ArrayList();

	protected List discardedElements = new ArrayList();

	protected List validCategories = new ArrayList();

	protected long publishing_start = 0;

	protected long time_for_external_link_checking = 0;

	// collect the elements referenced by the published contents so we can
	// publish them
	// this will be the elements to be published
	protected List referencedElements = new ArrayList();

	// published elements
	protected List publishedElements = new ArrayList();

	// this is the default target element for the content validator
	// set this before publishing the element and set to null after the
	// publishign is done
	protected MethodElement defaultTarget = null;

	/**
	 * consructor
	 * 
	 * @param pubDir
	 *            String
	 * @param validateExternalLinks
	 *            boolean
	 */
	public PublishingContentValidator(String pubDir, PublishHTMLOptions options) {
		super(pubDir);
		this.options = options;

		this.validateExternalLinks = options.isCheckExternalLinks();

		this.logPath = new File(pubDir, LOGS_FOLDER);
		super.info = getStream(INFO_LOG_FILENAME);
		super.warning = getStream(WARNING_LOG_FILENAME);
		super.error = getStream(ERROR_LOG_FILENAME);

		// set the start time
		publishing_start = Calendar.getInstance().getTimeInMillis();
	}

	/**
	 * dispose the object
	 */
	public void dispose() {
		invalidExternalLinks.clear();
		validatedExternalLinks.clear();
		missingReferences.clear();
		missingResources.clear();
		discardedElements.clear();
		validCategories.clear();

		referencedElements.clear();
		publishedElements.clear();

		info.close();
		warning.close();
		error.close();

	}

	protected PrintStream getStream(String fileName) {
		try {
			File f = new File(logPath, fileName);
			File dir = f.getParentFile();
			dir.mkdirs();

			if (!f.exists()) {
				f.createNewFile();
			}

			return new PrintStream(new FileOutputStream(f), true);
		} catch (Exception e) {

		}

		return null;
	}

	private IProxyService getProxyService() {
		Bundle bundle = Platform.getBundle(CORE_NET_BUNDLE);
		if (bundle != null) {
			BundleContext ctx = bundle.getBundleContext();
			String name = IProxyService.class.getName();
			ServiceReference ref = ctx.getServiceReference(name);
			if (ref != null)
				return (IProxyService) bundle.getBundleContext()
						.getService(ref);
		}
		return null;
	}

	/**
	 * validate the link attributes fro the element.
	 * 
	 * @param owner
	 *            MethodElement the owner element
	 * @param attributes
	 *            String the attributes in the link
	 * @param text
	 *            String the text allow with the link
	 * @param config
	 *            MethodConfiguration
	 * 
	 * @return LinkInfo
	 */
	public LinkInfo validateLink(MethodElement owner, String attributes,
			String text, MethodConfiguration config, String tag) {
		LinkInfo info = super
				.validateLink(owner, attributes, text, config, tag);

		if (validateExternalLinks) {

			String url = info.getUrl();
			if ((url != null) && ResourceHelper.isExternalLink(url)
					&& !url.startsWith("ftp://")) //$NON-NLS-1$
			{
				if (!validatedExternalLinks.contains(url)) {
					Timer t = new Timer();
					IProxyService proxyService = getProxyService();

					if (proxyService.isProxiesEnabled()) {
						IProxyData proxy = null;
						boolean accessible = false;
						boolean useProxy = false;
						String exceptionMessage = null;
						String[] proxyTypes = { IProxyData.HTTP_PROXY_TYPE,
								IProxyData.HTTPS_PROXY_TYPE,
								IProxyData.SOCKS_PROXY_TYPE };
						for (String proxyType : proxyTypes) {
							// access external link by using different proxys
							proxy = proxyService.getProxyData(proxyType);
							if ((proxy.getHost()==null)||proxy.getPort()==-1)
							{
								continue;
							}
							try {
								HttpResponse resp = HttpUtil.doGet(url, null,
										6000, proxy); // timeout
								useProxy = true;
								accessible = true;
								break;
							} catch (java.net.UnknownHostException e) {
							} catch (Exception e) {
								if (exceptionMessage == null)
								{
									exceptionMessage = proxy.getHost() + ":"
											+ proxy.getPort() + "[" + proxyType
											+ "]:" + e.getMessage();
								} else {
									exceptionMessage += ";" + proxy.getHost()
											+ ":" + proxy.getPort() + "["
											+ proxyType + "]:" + e.getMessage();
								}
							}
						}
						if (useProxy)
						{
							if (!accessible) {
								if (exceptionMessage != null) {
									logInvalidExternalLink(owner, url,
											exceptionMessage);
								} else {
									logInvalidExternalLink(owner, url, null);
								}
							}
						}
						else	// connect directly
						{
							try {
								HttpResponse resp = HttpUtil.doGet(url, null, 6000); // timeout
							} catch (java.net.UnknownHostException e) {
								logInvalidExternalLink(owner, url, null);
							} catch (Exception e) {
								logInvalidExternalLink(owner, url, e.getMessage());
							}
						}
						
					} else {
						try {
							HttpResponse resp = HttpUtil.doGet(url, null, 6000); // timeout
							// System.out
							// .println(time
							// + " mini-seconds querying Url '" + url + "',
							// return
							// status=" + resp.getStatus()); //$NON-NLS-1$
							// //$NON-NLS-2$
						} catch (java.net.UnknownHostException e) {
							logInvalidExternalLink(owner, url, null);
						} catch (Exception e) {
							logInvalidExternalLink(owner, url, e.getMessage());
						}
					}

					t.stop();
					time_for_external_link_checking += t.getTime();

					// cache it
					validatedExternalLinks.add(url);

					// do we need to log the info so that user know what
					// external
					// urls are referenced in the content?
					logInfo(owner, NLS.bind(
							PublishingResources.externalUrl_msg, new Object[] {
									new Integer(t.getTime()), url }));
				}

			}
		}
		return info;
	}

	/**
	 * log missing reference.
	 * 
	 * @param owner
	 *            MethodElement
	 * @param refElement
	 *            MethodElement the missing element
	 */
	public void logMissingReference(MethodElement owner,
			MethodElement refElement) {
		super.logMissingReference(owner, refElement);
		missingReferences.add(new MissingReference(owner, refElement));
	}

	/**
	 * log missing reference
	 * 
	 * @param owner
	 *            M<ethodElement
	 * @param guid
	 *            String the guid of the missing element
	 * @param linkedText
	 *            String the linked text.
	 */
	public void logMissingReference(MethodElement owner, String guid,
			String linkedText) {
		super.logMissingReference(owner, guid, linkedText);
		missingReferences.add(new MissingReference(owner, guid, linkedText));
	}

	/**
	 * log missing resource.
	 * 
	 * @param owner
	 *            MethodElement
	 * @param resourceFile
	 *            File
	 * @param url
	 *            String
	 */
	public void logMissingResource(MethodElement owner, File resourceFile,
			String url) {
		super.logMissingResource(owner, resourceFile, url);
		missingResources.add(new MissingResource(owner, resourceFile, url));
	}

	/**
	 * log invalid external link
	 * 
	 * @param owner
	 * @param url
	 *            String
	 * @param message
	 *            String
	 */
	public void logInvalidExternalLink(MethodElement owner, String url,
			String message) {
		super.logInvalidExternalLink(owner, url, message);
		invalidExternalLinks.add(new InvalidExternalLinkInfo(owner, url,
				message));
	}

	/**
	 * get report about the content validation.
	 * 
	 * @return XmlElement
	 */
	public XmlElement getReport() {
		XmlElement reportXml = new XmlElement("validatorInfo"); //$NON-NLS-1$

		if (invalidExternalLinks.size() > 0) {
			String msg = time_for_external_link_checking / 1000
					+ " seconds validating external links"; //$NON-NLS-1$
			System.out.println(msg);
			logInfo(msg);

			XmlElement invalidExternalLinksXml = reportXml
					.newChild("invalidExternalLinks"); //$NON-NLS-1$
			for (Iterator it = invalidExternalLinks.iterator(); it.hasNext();) {
				InvalidExternalLinkInfo info = (InvalidExternalLinkInfo) it
						.next();
				invalidExternalLinksXml
						.newChild("entry") //$NON-NLS-1$
						.setAttribute("url", info.url) //$NON-NLS-1$
						.setAttribute(
								"owner", (info.owner == null) ? "" : LibraryUtil.getLocalizeTypeName(info.owner)) //$NON-NLS-1$ //$NON-NLS-2$
						.setAttribute("message", info.message); //$NON-NLS-1$
			}
		}

		if (missingReferences.size() > 0) {
			XmlElement invalidReferencesXml = reportXml
					.newChild("invalidReferences"); //$NON-NLS-1$
			XmlElement missingReferencesXml = reportXml
					.newChild("missingReferences"); //$NON-NLS-1$
			for (Iterator it = missingReferences.iterator(); it.hasNext();) {
				MissingReference info = (MissingReference) it.next();
				if (info.refElement == null) {
					invalidReferencesXml
							.newChild("entry") //$NON-NLS-1$
							.setAttribute("element", info.linkedText) //$NON-NLS-1$
							.setAttribute("guid", info.guid) //$NON-NLS-1$
							.setAttribute(
									"owner", (info.owner == null) ? "" : LibraryUtil.getLocalizeTypeName(info.owner)); //$NON-NLS-1$ //$NON-NLS-2$
				} else {
					missingReferencesXml
							.newChild("entry") //$NON-NLS-1$
							.setAttribute(
									"element", (info.refElement == null) ? "" : LibraryUtil.getLocalizeTypeName(info.refElement)) //$NON-NLS-1$ //$NON-NLS-2$
							.setAttribute("guid", info.refElement.getGuid()) //$NON-NLS-1$
							.setAttribute(
									"owner", (info.owner == null) ? "" : LibraryUtil.getLocalizeTypeName(info.owner)); //$NON-NLS-1$ //$NON-NLS-2$
				}
			}
		}

		if (missingResources.size() > 0) {
			XmlElement missingResourcesXml = reportXml
					.newChild("missingResources"); //$NON-NLS-1$
			for (Iterator it = missingResources.iterator(); it.hasNext();) {
				MissingResource info = (MissingResource) it.next();
				missingResourcesXml
						.newChild("entry") //$NON-NLS-1$
						.setAttribute("url", info.url) //$NON-NLS-1$
						.setAttribute(
								"resource", (info.resourceFile == null) ? "" : info.resourceFile.getPath()) //$NON-NLS-1$ //$NON-NLS-2$
						.setAttribute(
								"owner", (info.owner == null) ? "" : LibraryUtil.getLocalizeTypeName(info.owner)); //$NON-NLS-1$ //$NON-NLS-2$

			}
		}

		long publishing_time = (Calendar.getInstance().getTimeInMillis() - publishing_start) / 1000;
		int minutes = (int) publishing_time / 60;
		int seconds = (int) publishing_time - minutes * 60;

		logInfo("Publishing time: " + minutes + " minutes " + seconds + " seconds"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		return reportXml;
	}

	/**
	 * add a category that should be published.
	 * 
	 * @param e
	 *            ContentCategory
	 */
	public void addValidCategory(ContentCategory e) {
		if (!validCategories.contains(e)) {
			validCategories.add(e);
		}
	}

	/**
	 * check if the element is discarded or not discarded elements will be
	 * treated as out side the configursation
	 * 
	 * @param owner
	 *            MethodElement the owner of the element
	 * @param feature
	 *            Object EStructuralFeature or OppositeFeature
	 * @param e
	 *            MethodElement the element to be checked
	 * 
	 * @return boolean
	 */
	public boolean isDiscarded(MethodElement owner, Object feature,
			MethodElement e) {
		if (discardedElements.contains(e)) {
			return true;
		}

		// if the element is a ContentCategory and is not discarded
		if (e instanceof ContentCategory) {
			if (validCategories.contains(e)) {
				return false;
			}

			// otherwise, check if it should be discarded or not
			// TODO
			// for now, discard all referenced content categories if they are
			// not included in the publishing view.
			// NO!!!!!!!!!!!! This will lead to a lot of broken links and
			// missing element
			// TOO strong limitation. Let open it for now
			// Publishing:Overview page in published website
			// have broken links to BM
			// return true;
			return false;
		}
		return false;
	}

	/**
	 * add a referenced element
	 * 
	 * @param owner
	 *            MethodElement
	 * @param e
	 *            MethodElement
	 */
	public void addReferencedElement(MethodElement owner, MethodElement e) {
		if (e == null) {
			return;
		}

		// don't add discarded elements
		if (isDiscarded(owner, null, e)) {
			if (debug) {
				System.out
						.println("Element is discarded: " + LibraryUtil.getLocalizeTypeName(e)); //$NON-NLS-1$
			}
			return;
		}

		if (e != null && !referencedElements.contains(e)
				&& !publishedElements.contains(e)) {
			referencedElements.add(e);
			logReference(owner, e);
		}
	}

	/**
	 * log a refernece
	 * 
	 * @param owner
	 *            MethodElement
	 * @param e
	 *            MethodElement
	 */
	public void logReference(MethodElement owner, MethodElement e) {
		if (debug) {
			System.out
					.println("--- Referenece Element Added: " + LibraryUtil.getLocalizeTypeName(e)); //$NON-NLS-1$
		}
	}

	/**
	 * remove element from referenced list
	 * 
	 * @param e
	 *            MethodElement
	 */
	public void removeReferencedElement(MethodElement e) {
		if (referencedElements.contains(e)) {
			referencedElements.remove(e);
			if (debug) {
				System.out
						.println("--- Reference Element Removed: " + LibraryUtil.getLocalizeTypeName(e)); //$NON-NLS-1$
			}
		}
	}

	/**
	 * get all the referenced elements
	 * 
	 * @return List
	 */
	public List getReferencedElements() {
		return referencedElements;
	}

	/**
	 * aet the discarded element for this publication. If an element is
	 * discarded, it should not be published and link to it should be link to
	 * mising element page
	 * 
	 * @param e
	 *            MethodElement
	 */
	public void setDiscardedElement(MethodElement e) {

		if (e == null) {
			return;
		}

		if (!discardedElements.contains(e)) {
			discardedElements.add(e);
		}

		// if th fdiscarded element is in the reference list, remove it as well
		removeReferencedElement(e);
	}

	/**
	 * check if an elenment is referenced or not.
	 * 
	 * @param e
	 *            MethodElement
	 * @return boolean
	 */
	public boolean isReferencedElement(MethodElement e) {
		return (e != null) && referencedElements.contains(e);
	}

	/**
	 * get the published elements
	 * 
	 * @return List
	 */
	public List getPublishedElements() {
		return publishedElements;
	}

	/**
	 * set the default target for the referenced elements
	 * 
	 * @param target
	 *            MethodElement
	 */
	public void setTargetElement(MethodElement target) {
		this.defaultTarget = target;
	}

	/**
	 * check if there is a closure or not
	 * 
	 * @return boolean
	 */
	public boolean hasClosure() {
		return false;
	}

	/**
	 * check if an element is in closure or not.
	 * 
	 * @param e
	 *            MethodElement
	 * @return boolean
	 */
	public boolean inClosure(MethodElement e) {
		return true;
	}

	/**
	 * add elements to closure
	 * 
	 * @param items
	 *            List
	 */
	public void addClosureElements(List items) {
		// do nothing
	}

	/**
	 * make a closure
	 * 
	 */
	public void makeElementClosure() {
		// do nothing
	}

	public boolean showBrokenLinks() {
		return !options.isConvertBrokenLinks();
	}

	/**
	 * get the flag on whether to show extra descriptor info. If true,
	 * information from linked element will be included in the descriptor page.
	 * 
	 * @return boolean
	 */
	public boolean showExtraInfoForDescriptors() {
		return options.isShowMethodContentInDescriptors();
	}

	/**
	 * show descriptors on method element page
	 */
	public boolean showRelatedDescriptors() {
		return options.showRelatedDescriptors;
	}

	/**
	 * get the tab id for the activity layout
	 * 
	 * @return String
	 */
	public String getDefaultActivityTab() {
		return options.getDefaultActivityTab();
	}
}
