//------------------------------------------------------------------------------
// 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.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 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;
	
	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$

	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,
			boolean validateExternalLinks) {
		super(pubDir);
		this.validateExternalLinks = validateExternalLinks;

		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;
	}

	/**
	 * 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) {
		LinkInfo info = super.validateLink(owner, attributes, text, config);

		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();
					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, t.getTime() + " mini-seconds " + NLS.bind(PublishingResources.externalUrl_msg,
							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$
						.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$
				} else {
					missingReferencesXml
							.newChild("entry") //$NON-NLS-1$
							.setAttribute(
									"element", (info.refElement == null ) ? "" : LibraryUtil.getLocalizeTypeName(info.refElement)) //$NON-NLS-1$
							.setAttribute("guid", info.refElement.getGuid()) //$NON-NLS-1$
							.setAttribute(
									"owner", (info.owner == null) ? "" : LibraryUtil.getLocalizeTypeName(info.owner)); //$NON-NLS-1$
				}
			}
		}

		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
	}

	/**
	 * 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 showExtraInfoForDescriptors;
	}

	/**
	 * set the flag
	 * 
	 * @param show boolean
	 */
	public void setShowExtraInfoForDescriptors(boolean show) {
		showExtraInfoForDescriptors = show;
	}
}
