/*******************************************************************************
 * Copyright (c) 2011 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 API and implementation
 *******************************************************************************/
package org.eclipse.wst.css.ui.internal.hyperlink;

import java.io.File;
import java.net.URI;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.wst.common.uriresolver.internal.provisional.URIResolverPlugin;
import org.eclipse.wst.css.core.internal.document.CSSRegionContainer;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.w3c.dom.css.CSSImportRule;
import org.w3c.dom.css.CSSPrimitiveValue;

/**
 * Detects hyperlink regions within CSS documents. This includes url() methods as
 * well as the resource referred to by @import 
 *
 */
public class CSSHyperlinkDetector extends AbstractHyperlinkDetector {

	/* (non-Javadoc)
	 * @see org.eclipse.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion, boolean)
	 */
	public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
		if (textViewer != null && region != null) {
			
			final IDocument document = textViewer.getDocument();
			final ICSSNode node = getNode(document, region);

			if (node == null) {
				return null;
			}
			String href = null;
			switch (node.getNodeType()) {
				case ICSSNode.PRIMITIVEVALUE_NODE:
					if (((CSSPrimitiveValue)node).getPrimitiveType() == CSSPrimitiveValue.CSS_URI) {
						href = ((CSSPrimitiveValue) node).getStringValue();
					}
					break;
				case ICSSNode.IMPORTRULE_NODE:
					href = ((CSSImportRule) node).getHref();
					break;
			}
			if (href != null) {
				final IHyperlink hyperlink = getHyperlink(node, href);
				if (hyperlink != null) {
					return new IHyperlink[] { hyperlink };
				}
			}
			
		}
		return null;
	}

	private ICSSNode getNode(IDocument document, IRegion region) {
		if (!(document instanceof IStructuredDocument))
			return null;

		IStructuredModel model = null;
		ICSSNode node = null;
		try {
			model = StructuredModelManager.getModelManager().getModelForRead((IStructuredDocument)document);
			node = (ICSSNode) model.getIndexedRegion(region.getOffset());
		}
		finally {
			if (model != null) {
				model.releaseFromRead();
			}
		}
		return node;
	}
	private IHyperlink getHyperlink(ICSSNode node, String href) {
		IHyperlink hyperlink = null;
		final String baseLocation = getBaseLocation(node.getOwnerDocument().getModel());
		if (baseLocation != null) {
			final String resolvedHref = URIResolverPlugin.createResolver().resolve(baseLocation, null, href);
			if (resolvedHref != null && isValidURI(resolvedHref)) {
				final IRegion hyperlinkRegion = getHyperlinkRegion(node, href);
				hyperlink = createHyperlink(resolvedHref, hyperlinkRegion);
			}
		}
		
		return hyperlink;
	}

	private IRegion getHyperlinkRegion(ICSSNode node, String href) {
		CSSRegionContainer uriRegion = null;
		switch (node.getNodeType()) {
			case ICSSNode.PRIMITIVEVALUE_NODE:
				uriRegion = (CSSRegionContainer) node;
				break;
			case ICSSNode.IMPORTRULE_NODE:
				ICSSNode attribute = node.getAttributes().getNamedItem("href"); //$NON-NLS-1$
				if (attribute instanceof CSSRegionContainer) {
					uriRegion = (CSSRegionContainer) attribute;
				}
				break;
		}
		if (uriRegion != null) {
			final int start = uriRegion.getStartOffset();
			final int end = uriRegion.getEndOffset();
			if (end > start)
				return new Region(start, end - start);
		}
		return null;
	}

	private IHyperlink createHyperlink(String href, IRegion region) {
		IHyperlink link = null;
		// try to locate the file in the workspace
		File systemFile = getFileFromUriString(href);
		if (systemFile != null) {
			String systemPath = systemFile.getPath();
			IFile file = getFile(systemPath);
			if (file != null) {
				// this is a WorkspaceFileHyperlink since file exists in
				// workspace
				link = new WorkspaceFileHyperlink(region, file);
			}
		}
		return link;
	}

	/**
	 * Returns an IFile from the given uri if possible, null if cannot find
	 * file from uri.
	 * 
	 * @param fileString
	 *            file system path
	 * @return returns IFile if fileString exists in the workspace
	 */
	private IFile getFile(String fileString) {
		IFile file = null;

		if (fileString != null) {
			Path filePath = new Path(fileString);
			if (filePath.segmentCount() > 1 && ResourcesPlugin.getWorkspace().getRoot().getFile(filePath).exists()) {
				return ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
			}
			IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(filePath);
			for (int i = 0; (i < files.length) && (file == null); i++) {
				if (files[i].exists()) {
					file = files[i];
				}
			}
		}

		return file;
	}

	/**
	 * Checks whether the given uriString is really pointing to a file
	 * 
	 * @param uriString
	 * @return boolean
	 */
	private boolean isValidURI(String uriString) {
		boolean isValid = false;
		File file = getFileFromUriString(uriString);

		if (file != null) {
			isValid = file.isFile();
		}
			
		return isValid;
	}

	/**
	 * Create a file from the given uri string
	 * 
	 * @param uriString -
	 *            assumes uriString is not http://
	 * @return File created from uriString if possible, null otherwise
	 */
	private File getFileFromUriString(String uriString) {
		File file = null;
		try {
			// first just try to create a file directly from uriString as
			// default in case create file from uri does not work
			file = new File(uriString);

			// try to create file from uri
			URI uri = new URI(uriString);
			file = new File(uri);
		}
		catch (Exception e) {
			// if exception is thrown while trying to create File just ignore
			// and file will be null
		}
		return file;
	}

	/**
	 * Get the base location from the current model (local file system)
	 */
	private String getBaseLocation(IStructuredModel model) {
		String result = null;

		// get the base location from the current model
		if (model != null) {
			result = model.getBaseLocation();

			IPath path = new Path(result);
			if (path.segmentCount() > 1) {
				IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
				if (file.exists()) {
					String baseLocation = null;
					if (file.getLocation() != null) {
						baseLocation = file.getLocation().toString();
					}
					if (baseLocation == null && file.getLocationURI() != null) {
						baseLocation = file.getLocationURI().toString();
					}
					if (baseLocation == null) {
						baseLocation = file.getFullPath().toString();
					}
					result = baseLocation;
				}
			}
		}
		return result;
	}
}
