/*=============================================================================#
 # Copyright (c) 2007, 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.ltk.ui.sourceediting.assist;

import java.io.File;
import java.util.Arrays;

import com.ibm.icu.text.Collator;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.lang.SystemUtils;
import org.eclipse.statet.jcommons.text.core.SearchPattern;
import org.eclipse.statet.jcommons.text.core.TextRegion;

import org.eclipse.statet.ecommons.runtime.core.util.PathUtils;
import org.eclipse.statet.ecommons.ui.SharedUIResources;

import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.ltk.ui.sourceediting.assist.SourceProposal.ProposalParameters;


/**
 * Content assist processor for completion of path for local file system resources.
 */
@NonNullByDefault
public abstract class PathCompletionComputor implements ContentAssistComputer {
	
	
	protected class ResourceCompletionProposal extends SourceProposal<AssistInvocationContext> {
		
		private final IFileStore fileStore;
		private final boolean isDirectory;
		/** The parent in the workspace, if in workspace */
		private final IContainer workspaceRef;
		
		private final String name;
		
		/** Final completion string */
		private @Nullable String completion;
		
		
		/**
		 * Creates a new completion proposal for a resource
		 * 
		 * @param offset the offset in the document where to insert the completion
		 * @param fileStore the EFS resource handle
		 * @param explicitName optional explicit name used instead of the name of the fileStore
		 * @param prefix optional prefix to prefix before the name
		 * @param workspaceRef the workspace resource handle, if the resource is in the workspace
		 */
		public ResourceCompletionProposal(final ProposalParameters<? extends AssistInvocationContext> parameters,
				final IFileStore fileStore, final String explicitName, final String prefix, final IContainer workspaceRef) {
			super(parameters);
			this.fileStore= fileStore;
			this.isDirectory= this.fileStore.fetchInfo().isDirectory();
			this.workspaceRef= workspaceRef;
			final StringBuilder name= new StringBuilder((explicitName != null) ? explicitName : this.fileStore.getName());
			if (prefix != null) {
				name.insert(0, prefix);
			}
			if (this.isDirectory) {
				name.append(PathCompletionComputor.this.fileSeparator);
			}
			this.name= name.toString();
		}
		
		
		@Override
		protected String getName() {
			return this.name;
		}
		
		
		@Override
		public String getSortingString() {
			return this.name;
		}
		
		
		@Override
		protected int computeReplacementLength(final int replacementOffset, final Point selection, final int caretOffset, final boolean overwrite) throws BadLocationException {
			int end= Math.max(caretOffset, selection.x + selection.y);
			if (overwrite) {
				final IDocument document= getInvocationContext().getSourceViewer().getDocument();
				final int length= document.getLength();
				while (end < length) {
					final char c= document.getChar(end);
					if (Character.isLetterOrDigit(c) || c == '_' || c == '.') {
						end++;
					}
					else {
						break;
					}
				}
				if (end >= length) {
					end= length;
				}
			}
			return (end - replacementOffset);
		}
		
		
		@Override
		public Image getImage() {
			Image image= null;
			if (this.workspaceRef != null) {
				final IResource member= this.workspaceRef.findMember(this.fileStore.getName(), true);
				if (member != null) {
					image= LTKUIPlugin.getInstance().getWorkbenchLabelProvider().getImage(member);
				}
			}
			if (image == null) {
				image= PlatformUI.getWorkbench().getSharedImages().getImage(
					this.isDirectory ? ISharedImages.IMG_OBJ_FOLDER : ISharedImages.IMG_OBJ_FILE);
			}
			return image;
		}
		
		
		private String getCompletion() {
			String completion= this.completion;
			if (completion == null) {
				final AssistInvocationContext context= getInvocationContext();
				final IDocument document= context.getDocument();
				completion= checkPathCompletion(document, getReplacementOffset(), this.name);
				this.completion= completion;
			}
			return completion;
		}
		
		@Override
		public CharSequence getPrefixCompletionText(final IDocument document, final int completionOffset) {
			return getCompletion();
		}
		
		@Override
		protected void doApply(final char trigger, final int stateMask, final int caretOffset,
				final int replacementOffset, final int replacementLength)
				throws BadLocationException {
			final AssistInvocationContext context= getInvocationContext();
			final IDocument document= context.getDocument();
			final ApplyData applyData= getApplyData();
//			final Point selectedRange= viewer.getSelectedRange();
			
			final String replacement= getCompletion();
			final Position newSelectionOffset= new Position(replacementOffset + replacementLength, 0);
			try {
				document.addPosition(newSelectionOffset);
				document.replace(replacementOffset, newSelectionOffset.getOffset() - replacementOffset, replacement);
				
				applyData.setSelection(newSelectionOffset.getOffset());
			}
			finally {
				document.removePosition(newSelectionOffset);
			}
			
			if (this.isDirectory) {
				reinvokeAssist();
			}
		}
		
	}
	
	
	private int searchMatchRules;
	
	private char fileSeparator;
	private char fileSeparatorBackup;
	
	private boolean isWindows;
	
	
	public PathCompletionComputor() {
	}
	
	
	@Override
	public void onSessionStarted(final ISourceEditor editor, final ContentAssist assist) {
		int matchRules= SearchPattern.PREFIX_MATCH;
		if (assist.getShowSubstringMatches()) {
			matchRules |= SearchPattern.SUBSTRING_MATCH;
		}
		this.searchMatchRules= matchRules;
		
		this.isWindows= getIsWindows();
		this.fileSeparator= getDefaultFileSeparator();
	}
	
	@Override
	public void onSessionEnded() {
	}
	
	
	protected int getSearchMatchRules() {
		return this.searchMatchRules;
	}
	
	protected boolean getIsWindows() {
		return SystemUtils.getLocalOs() == SystemUtils.OS_WIN;
	}
	
	protected final boolean isWindows() {
		return this.isWindows;
	}
	
	protected char getDefaultFileSeparator() {
		return (isWindows()) ? '\\' : '/';
	}
	
	protected char getSegmentSeparator() {
		return this.fileSeparator;
	}
	
	
	@Override
	public void computeCompletionProposals(final AssistInvocationContext context, final int mode,
			final AssistProposalCollector proposals, final IProgressMonitor monitor) {
		try {
			final int offset= context.getInvocationOffset();
			final TextRegion contentRange= getContentRegion(context, mode);
			if (contentRange == null
					|| offset < contentRange.getStartOffset() || offset > contentRange.getEndOffset()) {
				return;
			}
			
			String prefix= getPrefix(context, contentRange, offset);
			
			if (prefix == null) {
				return;
			}
			
			boolean needSeparatorBeforeStart= false; // including virtual separator
			String segmentPrefix= ""; //$NON-NLS-1$
			IFileStore baseStore= null;
			
			if (prefix.length() > 0 && prefix.charAt(prefix.length() - 1) == '.') {
				// prevent that path segments '.' and '..' at end are resolved by Path#canonicalize
				if (prefix.equals(".") || prefix.endsWith("/.") || (isWindows() && prefix.endsWith("\\."))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					prefix= prefix.substring(0, prefix.length() - 1);
					segmentPrefix= "."; //$NON-NLS-1$
				}
				else if (prefix.equals("..") || prefix.endsWith("/..") || (isWindows() && prefix.endsWith("\\.."))) { // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					prefix= prefix.substring(0, prefix.length() - 2);
					segmentPrefix= ".."; //$NON-NLS-1$
				}
			}
			IPath path= createPath(prefix);
			if (path == null) {
				return;
			}
			if (path.segmentCount() == 0) {
				if (isWindows() && path.getDevice() != null && !path.isRoot()) { // C: -> C:/
					path= path.addTrailingSeparator();
					needSeparatorBeforeStart= true;
				}
			}
			else if (// path.segmentCount() > 0 &&
					segmentPrefix.isEmpty() && !path.hasTrailingSeparator()) {
				segmentPrefix= path.lastSegment();
				path= path.removeLastSegments(1);
			}
			// on Windows, path starting with path separator are relative to the device of current directory
			if (path.isAbsolute() && isWindows() && path.getDevice() == null && !path.isUNC()) { 
				final IPath basePath= getRelativeBasePath();
				if (basePath != null) {
					path= path.setDevice(basePath.getDevice());
				}
			}
			
			baseStore= resolveStore(path);
			
			updatePathSeparator(prefix);
			
			String completionPrefix= (needSeparatorBeforeStart) ? Character.toString(this.fileSeparator) : null;
			
			if (baseStore == null || !baseStore.fetchInfo().exists()) {
				tryAlternative(context, path, offset - segmentPrefix.length(), segmentPrefix, 
						completionPrefix, proposals );
				return;
			}
			
			{	final ProposalParameters<? extends AssistInvocationContext> parameters= createProposalParameters(
						context, offset - segmentPrefix.length(), segmentPrefix);
				doAddChildren(parameters, baseStore, completionPrefix, proposals);
			}
			if (!segmentPrefix.isEmpty() && !segmentPrefix.equals(".")) { //$NON-NLS-1$
				baseStore= baseStore.getChild(segmentPrefix);
				if (baseStore.fetchInfo().exists()) {
					final StringBuilder prefixBuilder= new StringBuilder();
					if (completionPrefix != null) {
						prefixBuilder.append(completionPrefix);
					}
					prefixBuilder.append(baseStore.getName());
					prefixBuilder.append(this.fileSeparator);
					completionPrefix= prefixBuilder.toString();
					
					final ProposalParameters<?> parameters= createProposalParameters(
							context, offset - segmentPrefix.length(), ""); //$NON-NLS-1$
					parameters.baseRelevance= 20;
					doAddChildren(parameters, baseStore, completionPrefix, proposals);
				}
			}
			return;
		}
		catch (final BadLocationException e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, SharedUIResources.BUNDLE_ID, -1,
					"An error occurred while preparing path completions.", e), StatusManager.LOG);
		}
		catch (final CoreException e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, SharedUIResources.BUNDLE_ID, -1,
					"An error occurred while preparing path completions.", e), StatusManager.LOG);
		}
		finally {
			restorePathSeparator();
		}
	}
	
	@Override
	public void computeInformationProposals(final AssistInvocationContext context,
			final AssistProposalCollector proposals, final IProgressMonitor monitor) {
	}
	
	
	protected @Nullable String getPrefix(final AssistInvocationContext context,
			final TextRegion contentRegion, final int offset)
			throws BadLocationException {
		return checkPrefix(context.getSourceViewer().getDocument().get(
				contentRegion.getStartOffset(), offset - contentRegion.getStartOffset() ));
	}
	
	/**
	 * @param prefix to check
	 * @return the prefix, if valid, otherwise <code>null</code>
	 */
	protected @Nullable String checkPrefix(final @Nullable String prefix) {
		if (prefix == null) {
			return null;
		}
		final char[] breakingChars= "\n\r+<>|?*\"".toCharArray(); //$NON-NLS-1$
		for (int i= 0; i < breakingChars.length; i++) {
			if (prefix.indexOf(breakingChars[i]) >= 0) {
				return null;
			}
		}
		return prefix;
	}
	
	private @Nullable IPath createPath(String s) {
		if (isWindows() && File.separatorChar == '/') {
			s= s.replace('\\', '/');
		}
		return PathUtils.check(new Path(s));
	}
	
	private void updatePathSeparator(final String prefix) {
		final int lastBack= prefix.lastIndexOf('\\');
		final int lastForw= prefix.lastIndexOf('/');
		if (lastBack > lastForw) {
			this.fileSeparatorBackup= this.fileSeparator;
			this.fileSeparator= '\\';
		}
		else if (lastForw > lastBack) {
			this.fileSeparatorBackup= this.fileSeparator;
			this.fileSeparator= '/';
		}
		// else -1 == -1
	}
	
	private void restorePathSeparator() {
		if (this.fileSeparatorBackup != 0) {
			this.fileSeparator= this.fileSeparatorBackup;
			this.fileSeparatorBackup= 0;
		}
	}
	
	protected ProposalParameters<?> createProposalParameters(
			final AssistInvocationContext context, final int replacementOffset,
			final String pattern) {
		final ProposalParameters<?> parameters= new ProposalParameters<>(
				context, replacementOffset,
				new SearchPattern(getSearchMatchRules(), pattern) );
		parameters.baseRelevance= 20;
		return parameters;
	}
	
	protected void doAddChildren(final ProposalParameters<? extends AssistInvocationContext> parameters,
			final IFileStore baseStore,
			final String completionPrefix,
			final AssistProposalCollector proposals) throws CoreException {
		final IContainer[] workspaceRefs= ResourcesPlugin.getWorkspace().getRoot().findContainersForLocationURI(baseStore.toURI());
		final IContainer workspaceRef= (workspaceRefs.length > 0) ? workspaceRefs[0] : null;
		final String[] names= baseStore.childNames(EFS.NONE, new NullProgressMonitor());
		Arrays.sort(names, Collator.getInstance());
		for (final String name : names) {
			if (parameters.matchesNamePattern(name)) {
				proposals.add(new ResourceCompletionProposal(parameters,
						baseStore.getChild(name), null, completionPrefix,
						workspaceRef ));
			}
		}
	}
	
	
	protected abstract @Nullable TextRegion getContentRegion(AssistInvocationContext context, int mode)
			throws BadLocationException;
	
	protected @Nullable IPath getRelativeBasePath() {
		return null;
	}
	
	protected @Nullable IFileStore getRelativeBaseStore() {
		return null;
	}
	
	protected @Nullable IFileStore resolveStore(IPath path) throws CoreException {
		if (!path.isAbsolute()) {
			if (!isWindows() && path.getDevice() == null && "~".equals(path.segment(0))) { //$NON-NLS-1$
				final IPath homePath= new Path(System.getProperty(SystemUtils.USER_HOME_KEY));
				path= PathUtils.check(homePath.append(path.removeFirstSegments(1)));
			}
			else {
				final IFileStore base= getRelativeBaseStore();
				if (base != null) {
					return base.getFileStore(path);
				}
				return null;
			}
		}
		return EFS.getStore(URIUtil.toURI(path));
	}
	
	protected void tryAlternative(final AssistInvocationContext context,
			final IPath path,
			final int startOffset, final String segmentPrefix, final @Nullable String completionPrefix,
			final AssistProposalCollector proposals) throws CoreException {
	}
	
	/**
	 * Final check of completion string. 
	 * 
	 * E.g. to escape special chars.
	 * 
	 * @param document
	 * @param completionOffset
	 * @param completion
	 * 
	 * @return the checked completion string
	 * @throws BadLocationException
	 */
	protected String checkPathCompletion(final IDocument document, final int completionOffset,
			final String completion) {
		return completion;
	}
	
}
