/*=============================================================================#
 # Copyright (c) 2005, 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.templates;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;

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

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.templates.DocumentTemplateContext;
import org.eclipse.jface.text.templates.GlobalTemplateVariables;
import org.eclipse.jface.text.templates.SimpleTemplateVariableResolver;
import org.eclipse.jface.text.templates.TemplateBuffer;
import org.eclipse.jface.text.templates.TemplateContext;
import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.jface.text.templates.TemplateVariable;
import org.eclipse.jface.text.templates.TemplateVariableResolver;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.internal.ltk.ui.TemplatesMessages;
import org.eclipse.statet.ltk.core.ElementName;
import org.eclipse.statet.ltk.core.util.UserInfo;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.model.core.elements.IWorkspaceSourceUnit;


@NonNullByDefault
public class SourceEditorContextType extends TemplateContextType {
	
	
	public static class AuthorName extends SimpleTemplateVariableResolver {
		
		public AuthorName() {
			super("author_name", TemplatesMessages.Templates_Variable_AuthorName_description); //$NON-NLS-1$
		}
		
		@Override
		protected String resolve(final TemplateContext context) {
			return UserInfo.getAuthorInfo().getName();
		}
	}
	
	public static class AuthorEmail extends SimpleTemplateVariableResolver {
		
		public AuthorEmail() {
			super("author_email", TemplatesMessages.Templates_Variable_AuthorEmail_description); //$NON-NLS-1$
		}
		
		@Override
		protected String resolve(final TemplateContext context) {
			return UserInfo.getAuthorInfo().getEmail();
		}
	}
	
	
	/**
	 * Resolver that resolves to the variable defined in the context.
	 */
	protected static class CodeTemplatesVariableResolver extends TemplateVariableResolver {
		
		public CodeTemplatesVariableResolver(final String type, final String description) {
			super(type, description);
		}
		
		@Override
		protected @Nullable String resolve(final TemplateContext context) {
			return context.getVariable(getType());
		}
		
	}
	
	protected static class InitialSelectionStart extends TemplateVariableResolver {
		
		public InitialSelectionStart() {
			super(SELECT_START_VAR_NAME, TemplatesMessages.Templates_Variable_SelectionBegin_description);
		}
		
		@Override
		public void resolve(final TemplateVariable variable, final TemplateContext context) {
			variable.setValue(""); //$NON-NLS-1$
			variable.setUnambiguous(true);
		}
	}
	
	protected static class InitialSelectionEnd extends TemplateVariableResolver {
		
		public InitialSelectionEnd() {
			super(SELECT_END_VAR_NAME, TemplatesMessages.Templates_Variable_SelectionEnd_description);
		}
		
		@Override
		public void resolve(final TemplateVariable variable, final TemplateContext context) {
			variable.setValue(""); //$NON-NLS-1$
			variable.setUnambiguous(true);
		}
		
	}
	
	
	/**
	 * Resolver for file name.
	 */
	protected static class File extends SimpleTemplateVariableResolver {
		
		public File() {
			super(FILE_NAME_VAR_NAME, TemplatesMessages.Templates_Variable_File_description);
		}
		
		@Override
		protected String resolve(final TemplateContext context) {
			if (context instanceof IWorkbenchTemplateContext) {
				final ISourceUnit su= ((IWorkbenchTemplateContext) context).getSourceUnit();
				if (su != null) {
					final ElementName elementName= su.getElementName();
					if (elementName != null) {
						return elementName.getSegmentName();
					}
				}
			}
			return ""; //$NON-NLS-1$
		}
	}
	
	/**
	 * Resolver for project name.
	 */
	protected static class Project extends SimpleTemplateVariableResolver {
		
		public Project() {
			super("enclosing_project", TemplatesMessages.Templates_Variable_EnclosingProject_description); //$NON-NLS-1$
		}
		
		@Override
		protected String resolve(final TemplateContext context) {
			if (context instanceof IWorkbenchTemplateContext) {
				final ISourceUnit su= ((IWorkbenchTemplateContext) context).getSourceUnit();
				if (su instanceof IWorkspaceSourceUnit) {
					return ((IWorkspaceSourceUnit) su).getResource().getProject().getName();
				}
			}
			return ""; //$NON-NLS-1$
		}
	}
	
	/**
	 * Resolver for ToDo-tags. Intend to extend and overwrite {@link #getTag(ISourceUnit)}
	 */
	protected static class Todo extends SimpleTemplateVariableResolver {
		
		public Todo() {
			super("todo", TemplatesMessages.Templates_Variable_ToDo_description);  //$NON-NLS-1$
		}
		
		@Override
		protected String resolve(final TemplateContext context) {
			if (context instanceof IWorkbenchTemplateContext) {
				final String tag= getTag(((IWorkbenchTemplateContext) context).getSourceUnit());
				if (tag != null) {
					return tag;
				}
			}
			return "TODO"; //$NON-NLS-1$
		}
		
		protected @Nullable String getTag(final @Nullable ISourceUnit su) {
			return null;
		}
		
	}
	
	private static class MyLineSelection extends GlobalTemplateVariables.LineSelection {
		
		@Override
		protected String resolve(final TemplateContext context) {
			String value= super.resolve(context);
			final int length= value.length();
			if (length > 0 && context instanceof DocumentTemplateContext) {
				final char c= value.charAt(length-1);
				if (c != '\n' && c != '\r') {
					value+= TextUtilities.getDefaultLineDelimiter(((DocumentTemplateContext) context).getDocument());
				}
			}
			return value;
		}
		
	}
	
	
	public static final String FILE_NAME_VAR_NAME= "file_name"; //$NON-NLS-1$
	public static final String SELECT_START_VAR_NAME= "selection_begin"; //$NON-NLS-1$
	public static final String SELECT_END_VAR_NAME= "selection_end"; ////$NON-NLS-1$
	
	
	public SourceEditorContextType(final String id, final String name) {
		super(id, name);
	}
	
	public SourceEditorContextType(final String id) {
		super(id);
	}
	
	public SourceEditorContextType() {
		super();
	}
	
	
	protected void addCommonVariables() {
		addResolver(new GlobalTemplateVariables.Dollar());
		addResolver(new GlobalTemplateVariables.Date());
		addResolver(new GlobalTemplateVariables.Year());
		addResolver(new GlobalTemplateVariables.Time());
		addResolver(new GlobalTemplateVariables.User());
		addResolver(new AuthorName());
		addResolver(new AuthorEmail());
		addResolver(new Project());
	}
	
	protected void addEditorVariables() {
		addResolver(new GlobalTemplateVariables.Cursor());
		addResolver(new GlobalTemplateVariables.WordSelection());
		addResolver(new MyLineSelection());
	}
	
	protected void addSourceUnitGenerationVariables() {
		addResolver(new File());
		addResolver(new InitialSelectionStart());
		addResolver(new InitialSelectionEnd());
	}
	
	
	@Override
	public void resolve(final TemplateBuffer buffer, final TemplateContext context) throws MalformedTreeException, BadLocationException {
		nonNullAssert(context);
		final TemplateVariable[] variables= buffer.getVariables();
		
		final IDocument document= new Document(buffer.getString());
		final List<TextEdit> positions= TemplateUtils.variablesToPositions(variables);
		final List<TextEdit> edits= new ArrayList<>(5);
		
		
		// iterate over all variables and try to resolve them
		for (int i= 0; i != variables.length; i++) {
			final TemplateVariable variable= variables[i];
			
			if (variable.isUnambiguous()) {
				continue;
			}
			
			// remember old values
			final int[] oldOffsets= variable.getOffsets();
			final int oldLength= variable.getLength();
			final String oldValue= variable.getDefaultValue();
			
			final String type= variable.getType();
			TemplateVariableResolver resolver= getResolver(type);
			if (resolver == null) {
				resolver= new TemplateVariableResolver();
				resolver.setType(type);
			}
			
			resolver.resolve(variable, context);
			
			final String value= variable.getDefaultValue();
			final String[] ln= document.getLegalLineDelimiters();
			final boolean multiLine= (TextUtilities.indexOf(ln, value, 0)[0] != -1);
			
			if (!oldValue.equals(value)) {
				// update buffer to reflect new value
				for (int k= 0; k != oldOffsets.length; k++) {
					String thisValue= value;
					if (multiLine) {
						final String indent= TemplateUtils.searchIndentation(document, oldOffsets[k]);
						if (indent.length() > 0) {
							final StringBuilder temp= new StringBuilder(thisValue);
							int offset= 0;
							while (true) {
								final int[] search= TextUtilities.indexOf(ln, temp.toString(), offset);
								if (search[0] == -1) {
									break;
								}
								offset= search[0] + ln[search[1]].length();
								temp.insert(offset, indent);
								offset+= indent.length();
							}
							thisValue= temp.toString();
						}
					}
					edits.add(new ReplaceEdit(oldOffsets[k], oldLength, thisValue));
				}
			}
		}
		
		final MultiTextEdit edit= new MultiTextEdit(0, document.getLength());
		edit.addChildren(positions.toArray(new TextEdit[positions.size()]));
		edit.addChildren(edits.toArray(new TextEdit[edits.size()]));
		edit.apply(document, TextEdit.UPDATE_REGIONS);
		
		TemplateUtils.positionsToVariables(positions, variables);
		
		buffer.setContent(document.get(), variables);
	}
	
	
	@Override
	public int hashCode() {
		return getId().hashCode();
	}
	
	@Override
	public boolean equals(final @Nullable Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj instanceof SourceEditorContextType) {
			final SourceEditorContextType other= (SourceEditorContextType) obj;
			return getId().equals(other.getId());
		}
		return false;
	}
	
}
