//------------------------------------------------------------------------------
// 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.library.layout;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;

import org.eclipse.epf.common.xml.XSLTProcessor;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.layout.util.XmlElement;
import org.eclipse.epf.library.layout.util.XmlHelper;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.ProcessComponent;

/**
 * class to process an element link in the content
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public class LinkInfo {

	public static final String LINK_ATTR_CLASS = "class"; //$NON-NLS-1$

	public static final String LINK_ATTR_GUID = "guid"; //$NON-NLS-1$

	public static final String LINK_ATTR_HREF = "href"; //$NON-NLS-1$

	public static final String LINK_ATTR_KEY = "key"; //$NON-NLS-1$

	public static final String LINK_ATTR_TEXT = "text"; //$NON-NLS-1$

	public static final String LINK_ATTR_NAME = "name"; //$NON-NLS-1$

	private String linkedText = ""; //$NON-NLS-1$

	private MethodElement linkElement = null;

	private MethodElement ownerElement = null;

	private boolean isMissingReference = false;

	private Map attributeMap = new LinkedHashMap();

	private IContentValidator validator;

	private String pubDir;

	/**
	 * constructor
	 * 
	 * @param owner
	 * @param validator
	 * @param pubDir
	 */
	public LinkInfo(MethodElement owner, IContentValidator validator,
			String pubDir) {
		this.ownerElement = owner;
		this.validator = validator;
		this.pubDir = pubDir;
	}

	/**
	 * is this an element link?
	 * @return boolean
	 */
	public boolean isElementLink() {
		return ResourceHelper.isElementLink(getElementLinkType());
	}

	/**
	 * get the element link type
	 * @return String
	 */
	public String getElementLinkType() {
		return getAttribute(LINK_ATTR_CLASS);
	}

	/**
	 * get the guid of the element link
	 * @return String
	 */
	public String getGuid() {
		return getAttribute(LINK_ATTR_GUID);
	}

	/**
	 * get the url of the link
	 * @return String
	 */
	public String getUrl() {
		return getAttribute(LINK_ATTR_HREF);
	}

	/**
	 * get the linked text
	 * @return String
	 */
	public String getLinkedText() {
		return linkedText;
	}

	/**
	 * get the linked element
	 * @return MethodElement
	 */
	public MethodElement getLinkedElement() {
		return linkElement;
	}

	/**
	 * get the html for the link.
	 * 
	 * @param showBrokenLinks boolean true to show the broken link mark. false to show text only
	 * @return StringBuffer
	 */
	public StringBuffer getHtml(boolean showBrokenLinks) {
		StringBuffer buffer = new StringBuffer();

		if (isMissingReference && (pubDir != null)) {
			String url = "";
			if (!showBrokenLinks) {
				buffer.append(linkedText);
				return buffer;
			}

			url = getMissingElementUrl();
			buffer
					.append("<img alt=\"\" src=\"" + ResourceHelper.getBackPath(ownerElement) + "images/no_rup.gif\">&#160;"); //$NON-NLS-1$ //$NON-NLS-2$

			setUrl(url);
		}

		buffer.append("<a"); //$NON-NLS-1$

		for (Iterator it = attributeMap.entrySet().iterator(); it.hasNext();) {
			Map.Entry entry = (Map.Entry) it.next();
			String key = (String) entry.getKey();
			String value = (String) entry.getValue();
			if (LINK_ATTR_HREF.equals(key)
					&& (value == null || value.length() == 0)) {
				continue;
			}

			buffer.append(" ") //$NON-NLS-1$
					.append(entry.getKey()).append("=") //$NON-NLS-1$
					.append("\"").append(entry.getValue()).append("\""); //$NON-NLS-1$ //$NON-NLS-2$
		}

		buffer.append(">").append(linkedText).append("</a>"); //$NON-NLS-1$ //$NON-NLS-2$

		return buffer;
	}

	/**
	 * validate the link attributes
	 * @param attributes String the link attributes
	 * @param text String the linked text
	 * @param config MethodConfiguration
	 */
	public void validateLink(String attributes, String text,
			MethodConfiguration config) {
		this.linkedText = text;

		Matcher m2 = ResourceHelper.p_tag_attributes.matcher(attributes);
		while (m2.find()) {
			String attrName = m2.group(1).trim().toLowerCase();
			String attrValue = m2.group(3).trim();
			/*
			 * if (attrValue.startsWith("\"")) { attrValue =
			 * attrValue.substring(1); } if (attrValue.endsWith("\"")) {
			 * attrValue = attrValue.substring(0, attrValue.length() - 1); }
			 */

			// GVT: Cannot Preview/Browse Description Tab when
			// the CP contains chinese characters
			// generated html from xslt got the href urls encoded. we don't want
			// that make sure decode the url using "UTF-8" encoding
			if (attrName.equals(LINK_ATTR_HREF)) {
				try {
					attrValue = decode(attrValue);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			attributeMap.put(attrName, attrValue);
		}

		String guid = getGuid();
		if (guid == null) {
			// check if the file contains guid, if yes, need to get the element
			String url = getUrl();
			guid = ResourceHelper.getGuidFromFileName(url);
			if (guid != null) {
				setGuid(guid);
			}
		}

		validateElementUrl(config);
	}

	protected String decode(String str) throws UnsupportedEncodingException {
		return URLDecoder.decode(str, "UTF-8"); //$NON-NLS-1$
	}

	/**
	 * get attribute
	 * @param name
	 * @return String
	 */
	private String getAttribute(String name) {
		return (String) attributeMap.get(name);
	}

	/**
	 * set guid
	 * @param guid String
	 */
	private void setGuid(String guid) {
		attributeMap.put(LINK_ATTR_GUID, guid);
	}

	private void setUrl(String url) {
		attributeMap.put(LINK_ATTR_HREF, url);
	}

	private void validateElementUrl(MethodConfiguration config) {
		String guid = getGuid();
		if (guid != null) {
			MethodElement e = null;
			ILibraryManager manager = LibraryService.getInstance()
					.getCurrentLibraryManager();
			if (manager != null) {
				e = manager.getMethodElement(guid);
			}

			// if process component, get show the process
			if (e instanceof ProcessComponent) {
				e = ((ProcessComponent) e).getProcess();
			}

			// 156474 - Process Package (either CP package or DP package) can
			// not be linked in RTE
			// don't show link for packages.
			if (e instanceof MethodPackage || e instanceof MethodConfiguration
					|| e instanceof MethodLibrary) {
				e = null;
				// remove the link atytribute
				setUrl(null);
				return;
			}

			if (e != null) {
				if (config != null) {
					MethodElement e1 = ConfigurationHelper
							.getCalculatedElement(e, config);
					if (e1 != null) {
						e = e1;
					} else {
						isMissingReference = true;
						validator.logMissingReference(ownerElement, e);
					}
				}
			} else {
				isMissingReference = true;
				validator.logMissingReference(ownerElement, guid, linkedText);
			}

			if (e != null) {
				guid = e.getGuid();
				setGuid(guid);
				String url = getUrl();

				// url can be null, for example, an element link for
				// presentation name, such as
				// <a class="PresentationName"
				// guid="{EE97A8CD-66CA-4A9B-9871-E3B94CCED528}">Project
				// Manager</a>
				// we only need to get the element from the guid
				if (url != null) {
					url = url.trim();
					if (!url.toLowerCase().startsWith(
							ResourceHelper.URL_STR_JAVASCRIPT)) {
						url = ResourceHelper.getUrl(e, ownerElement,
								ResourceHelper.FILE_EXT_HTML, url);
						setUrl(url);
					}
				}

				if (isElementLink()) {
					String text = ResourceHelper.getLinkText(e,
							getElementLinkType());
					if (text != null) {
						// if null, can be used text, don't reset it
						this.linkedText = text;
					}
				}

				if (validator.isDiscarded(ownerElement, null, e)) {
					isMissingReference = true;
					validator.logMissingReference(ownerElement, e);
					e = null; // ignore the element since it's discarded
				}
			}

			this.linkElement = e;

		}
	}

	// private static final String MISSING_PAGES_XSL = "pages_not_installed/";
	// //$NON-NLS-1$
	private String getMissingElementUrl() {
		if (!isMissingReference) {
			return ""; //$NON-NLS-1$
		}

		String url = null;

		// if (linkElement == null) {
		// // this is an invalid element, maybe deleted from the library
		// // already
		// url = ResourceHelper.MISSING_PAGES_FOLDER + getGuid()
		// + ResourceHelper.FILE_EXT_HTML;
		// } else {
		// url = ResourceHelper.MISSING_PAGES_FOLDER
		// + ResourceHelper.getFileName(linkElement,
		// ResourceHelper.FILE_EXT_HTML);
		// }

		url = ResourceHelper.MISSING_PAGES_FOLDER + "pages_not_installed"
				+ ResourceHelper.FILE_EXT_HTML;

		File f = new File(pubDir, url);
		File dir = f.getParentFile();
		if (!dir.exists()) {
			dir.mkdirs();
		}

		// if ( !f.exists() )
		{
			// generate the html file
			XmlElement xml = new XmlElement("Element"); //$NON-NLS-1$
			if (linkElement == null) {
				xml.setAttribute("invalidLink", "true") //$NON-NLS-1$ //$NON-NLS-2$
						.setAttribute("guid", getGuid()) //$NON-NLS-1$
						.setAttribute("name", linkedText); //$NON-NLS-1$
			} else {
				xml
						.setAttribute("guid", getGuid()) //$NON-NLS-1$
						.setAttribute("type", linkElement.getType().getName()) //$NON-NLS-1$
						.setAttribute("name", linkElement.getName()) //$NON-NLS-1$
						.setAttribute(
								"pluginName", LibraryUtil.getMethodPlugin(linkElement).getName()); //$NON-NLS-1$
			}
			String xslPath = LayoutResources.getXslUri(
					"page_not_installed", null); //$NON-NLS-1$
			saveHtml(xml, xslPath, f);
		}

		return ResourceHelper.getBackPath(ownerElement).replace(
				File.separatorChar, '/')
				+ url;
	}

	/**
	 * save a html file 
	 * @param xmlElement
	 * @param xsl_uri
	 * @param outputFile
	 * @deprecated this method id not used any more
	 */
	public void saveHtml(XmlElement xmlElement, String xsl_uri, File outputFile) {
		try {
			StringBuffer xml = new StringBuffer();
			xml.append(XmlHelper.XML_HEADER).append(xmlElement.toXml());

			OutputStreamWriter output = new OutputStreamWriter(
					new FileOutputStream(outputFile), "utf-8"); //$NON-NLS-1$
			Properties xslParams = LibraryPlugin.getDefault().getProperties(
					"/layout/xsl/resources.properties"); //$NON-NLS-1$

			XSLTProcessor.transform(xsl_uri, xml.toString(), xslParams, output);
			output.flush();
			output.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

}
