/*******************************************************************************
 * Copyright (c) 2004 - 2006 University Of British Columbia 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:
 *     University Of British Columbia - initial API and implementation
 *******************************************************************************/
package org.eclipse.mylyn.internal.bugs.java;

import java.util.List;

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.Comment;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.TextElement;
import org.eclipse.jdt.internal.corext.dom.NodeFinder;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.mylyn.internal.bugzilla.ui.BugzillaHyperlinkUtil;
import org.eclipse.mylyn.internal.core.util.MylarStatusHandler;
import org.eclipse.mylyn.provisional.tasklist.TaskRepository;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.texteditor.ITextEditor;

/**
 * @author Shawn Minto
 * Detects bugzilla hyperlinks within source code
 */
public class BugzillaHyperLinkDetector extends AbstractHyperlinkDetector {

	private TaskRepository repository;
	
	public BugzillaHyperLinkDetector(TaskRepository repository) {
		this.repository = repository;
	}
	
	@SuppressWarnings("unchecked")
	public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
		
		ITextEditor textEditor = getEditor();
		if (region == null || textEditor == null || canShowMultipleHyperlinks || !(textEditor instanceof JavaEditor))
			return null;

		IEditorSite site = textEditor.getEditorSite();
		if (site == null)
			return null;

		IJavaElement javaElement;
		Object adapter = textEditor.getEditorInput().getAdapter(IJavaElement.class);
		if (adapter instanceof IJavaElement) {
			javaElement = (IJavaElement)adapter;
		} else {
			return null;
		}
		
		if (javaElement == null)
			return null;

		CompilationUnit ast = JavaPlugin.getDefault().getASTProvider().getAST(javaElement, ASTProvider.WAIT_NO, null);
		if (ast == null)
			return null;

		ASTNode node = NodeFinder.perform(ast, region.getOffset(), 1);

		if (node == null || !(node instanceof TextElement || node instanceof Block))
			return null;

		String comment = null;
		int commentStart = -1;

		if (node instanceof TextElement) {
			TextElement element = (TextElement) node;
			comment = element.getText();
			commentStart = element.getStartPosition();
		} else if (node instanceof Block) {
			Comment c = findComment(ast.getCommentList(), region.getOffset(), 1);
			if (c != null) {
				try {
					IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput());
					String commentString = document.get(c.getStartPosition(), c.getLength());
					comment = getStringFromComment(c, region.getOffset(), commentString);
					commentStart = getLocationFromComment(c, comment, commentString) + c.getStartPosition();
				} catch (BadLocationException e) {
					MylarStatusHandler.log(e, "Failed to get text for comment");
				}
			}
		}

		if (comment == null)
			return null;

		int startOffset = region.getOffset();
		int endOffset = startOffset + region.getLength();
		
		return BugzillaHyperlinkUtil.findBugHyperlinks(repository.getUrl(), startOffset, endOffset, comment, commentStart);
	}

//	private IHyperlink[] findBugHyperlinks(int startOffset, int endOffset, String comment, int commentStart) {
//
//		Pattern p = Pattern.compile("^.*bug\\s+\\d+.*");
//		Matcher m = p.matcher(comment.toLowerCase().trim());
//		boolean b = m.matches();
//
//		p = Pattern.compile("^.*bug#\\s+\\d+.*");
//		m = p.matcher(comment.toLowerCase().trim());
//		boolean b2 = m.matches();
//
//		p = Pattern.compile("^.*bug\\s#\\d+.*");
//		m = p.matcher(comment.toLowerCase().trim());
//		boolean b3 = m.matches();
//
//		p = Pattern.compile("^.*bug#\\d+.*");
//		m = p.matcher(comment.toLowerCase().trim());
//		boolean b4 = m.matches();
//
//		// XXX walk forward from where we are
//		if (b || b2 || b3 || b4) {
//
//			int start = comment.toLowerCase().indexOf("bug");
//			int ahead = 4;
//			if (b2 || b3 || b4) {
//				int pound = comment.toLowerCase().indexOf("#", start);
//				ahead = pound - start + 1;
//			}
//			String endComment = comment.substring(start + ahead, comment.length());
//			endComment = endComment.trim();
//			int endCommentStart = comment.indexOf(endComment);
//
//			int end = comment.indexOf(" ", endCommentStart);
//			int end2 = comment.indexOf(":", endCommentStart);
//
//			if ((end2 < end && end2 != -1) || (end == -1 && end2 != -1)) {
//				end = end2;
//			}
//
//			if (end == -1)
//				end = comment.length();
//
//			try {
//				int bugId = Integer.parseInt(comment.substring(endCommentStart, end).trim());
//
//				start += commentStart;
//				end += commentStart;
//
//				if (startOffset >= start && endOffset <= end) {
//					IRegion sregion = new Region(start, end - start);
//					return new IHyperlink[] { new BugzillaHyperLink(sregion, bugId) };
//				}
//			} catch (NumberFormatException e) {
//				return null;
//			}
//		}
//		return null;
//	}

	private int getLocationFromComment(Comment c, String commentLine, String commentString) {
		if (commentLine == null) {
			return -1;
		} else {
			return commentString.indexOf(commentLine);
		}
	}

	private String getStringFromComment(Comment comment, int desiredOffset, String commentString) {
		String[] parts = commentString.split("\n");
		if (parts.length > 1) {
			int offset = comment.getStartPosition();
			for (String part : parts) {
				int newOffset = offset + part.length() + 1;
				if (desiredOffset >= offset && desiredOffset <= newOffset) {
					return part;
				}

			}
		} else {
			return commentString;
		}

		return null;
	}

	private Comment findComment(List<Comment> commentList, int offset, int i) {
		for (Comment comment : commentList) {
			if (comment.getStartPosition() <= offset
					&& (comment.getStartPosition() + comment.getLength() >= offset + i)) {
				return comment;
			}
		}
		return null;
	}
}
