//------------------------------------------------------------------------------
// 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.Locale;
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.persistence.ILibraryResourceSet;
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<String, String> attributeMap = new LinkedHashMap<String, String>();

	private IContentValidator validator;

	private String pubDir;
	
	private String tag;
	
	//Temp solution for getting around without having a libMgr during migration
	//Should be removed when lib loaded during migration is registed with Lib service.
	private static MethodLibrary library;

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

	/**
	 * 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 = ""; //$NON-NLS-1$
			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("<" + tag); //$NON-NLS-1$

		for (Iterator<Map.Entry<String, String>> it = attributeMap.entrySet().iterator(); it.hasNext();) {
			Map.Entry<String, String> entry = it.next();
			String key = entry.getKey();
			String value = 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("</" + tag + ">"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		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 = ""; //$NON-NLS-1$
			if (m2.group(3) != null) {
				attrValue = m2.group(3).trim();
			} else if (m2.group(2) != null) {
				attrValue = m2.group(2).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;
			e = 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() && !tag.equals("area")) { //$NON-NLS-1$
					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;

		}
	}

	public static MethodElement getMethodElement(String guid) {
		MethodElement e;
		ILibraryManager manager = LibraryService.getInstance()
				.getCurrentLibraryManager();
		if (manager != null && getLibrary() == null) {
			e = manager.getMethodElement(guid);
		} else {
			e = getMethodElement_(guid);
			if (e == null && manager != null) {
				e = manager.getMethodElement(guid);
			}
		}
		return 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" //$NON-NLS-1$
				+ 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$
			
			
			Locale locale = Locale.getDefault();
			String lang = locale.getLanguage();
			xml.setAttribute("lang", lang); //$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.getDefaultXslPath(
					"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();
		}
	}
	
	private static MethodElement getMethodElement_(String guid) {
				try {
					if (getLibrary() == null) {
						return null;
					}
					ILibraryResourceSet resourceSet = (ILibraryResourceSet) getLibrary()
							.eResource().getResourceSet();
					if (resourceSet != null) {
						return (MethodElement) resourceSet.getEObject(guid);
					}
				} catch (Throwable th) {
					// Log error here
					th.printStackTrace();
				}
				return null;
			}

	public static MethodLibrary getLibrary() {
		return library;
	}

	public static void setLibrary(MethodLibrary library) {
		LinkInfo.library = library;
	}

}
