//------------------------------------------------------------------------------
// 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"; //$NON-NLS-1$

	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() + ":" //$NON-NLS-1$
											+ proxy.getPort() + "[" + proxyType //$NON-NLS-1$
											+ "]:" + e.getMessage(); //$NON-NLS-1$
								} else {
									exceptionMessage += ";" + proxy.getHost() //$NON-NLS-1$
											+ ":" + proxy.getPort() + "["		//$NON-NLS-1$ //$NON-NLS-2$
											+ proxyType + "]:" + e.getMessage(); //$NON-NLS-1$
								}
							}
						}
						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();
	}
}
