/*=============================================================================#
 # Copyright (c) 2009, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.r.ui.editors;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
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.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlink;

import org.eclipse.statet.ecommons.io.FileUtil;
import org.eclipse.statet.ecommons.text.ui.OpenFileHyperlink;

import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.model.core.elements.IWorkspaceSourceUnit;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.r.core.source.IRDocumentConstants;


public class RFileHyperlinkDetector extends AbstractHyperlinkDetector {
	
	
	public RFileHyperlinkDetector() {
	}
	
	
	@Override
	public IHyperlink[] detectHyperlinks(final ITextViewer textViewer, final IRegion region,
			final boolean canShowMultipleHyperlinks) {
		try {
			final ISourceEditor editor= getAdapter(ISourceEditor.class);
			if (editor == null) {
				return null;
			}
			
			final List<IHyperlink> hyperlinks= new ArrayList<>(4);
			final IDocument document= textViewer.getDocument();
			int start= 0;
			int stop= 0;
			
			final ITypedRegion partition= TextUtilities.getPartition(document,
					editor.getDocumentContentInfo().getPartitioning(), region.getOffset(), false );
			if (partition != null && partition.getLength() > 3) {
				if (partition.getType().equals(IRDocumentConstants.R_COMMENT_CONTENT_TYPE)
						|| partition.getType().equals(IRDocumentConstants.R_ROXYGEN_CONTENT_TYPE) ) {
					boolean quote= false;
					start= region.getOffset();
					{	final int bound= partition.getOffset()+1;
						{	final char c= document.getChar(start);
							if (c <= 0x22 || c == '>' || c == '<') {
								return null;
							}
						}
						while (start > bound) {
							final char c= document.getChar(start-1);
							if (c <= 0x22 || c == '>' || c == '<') {
								if (c == '"') {
									quote= true;
								}
								break;
							}
							start--;
						}
					}
					{	final int bound= partition.getOffset()+partition.getLength();
						stop= region.getOffset()+1;
						while (stop < bound) {
							final char c= document.getChar(stop);
							if (c <= 0x22 || c == '>' || c == '<') {
								if (quote || c != '"') {
									break;
								}
							}
							stop++;
						}
					}
				}
				else if (partition.getType().equals(IRDocumentConstants.R_STRING_CONTENT_TYPE)) {
					start= partition.getOffset()+1;
					stop= partition.getOffset()+partition.getLength();
					if (document.getChar(stop-1) == document.getChar(partition.getOffset())) {
						stop--;
					}
				}
				
				if (start >= stop) {
					return null;
				}
				IContainer relativeBase= null;
				
				final ISourceUnit su= editor.getSourceUnit();
				if (su instanceof IWorkspaceSourceUnit) {
					final IResource resource= ((IWorkspaceSourceUnit) su).getResource();
//					final IRProject rProject= RProjects.getRProject(resource.getProject());
//					if (rProject != null) {
//						relativeBase= rProject.getRawBuildpath();
//					}
					if (relativeBase == null) {
						relativeBase= resource.getParent();
					}
				}
				final IFileStore store= FileUtil.getLocalFileStore(
						document.get(start, stop-start), relativeBase );
				if (store != null) {
					final IFileInfo info= store.fetchInfo();
					if (info.exists() && !store.fetchInfo().isDirectory()) {
						hyperlinks.add(new OpenFileHyperlink(new Region(start, stop-start), store));
					}
				}
			}
			if (!hyperlinks.isEmpty()) {
				return hyperlinks.toArray(new IHyperlink[hyperlinks.size()]);
			}
		}
		catch (final BadLocationException | CoreException e) {}
		return null;
	}
	
}
