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

import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateBuffer;
import org.eclipse.jface.text.templates.TemplateVariable;
import org.eclipse.osgi.util.NLS;

import org.eclipse.statet.ecommons.templates.TemplateMessages;

import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.ltk.model.core.elements.IModelElement;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.ui.templates.TemplateUtils;
import org.eclipse.statet.ltk.ui.templates.TemplateUtils.EvaluatedTemplate;
import org.eclipse.statet.r.core.RResourceUnit;
import org.eclipse.statet.r.core.model.ArgsDefinition;
import org.eclipse.statet.r.core.model.ArgsDefinition.Arg;
import org.eclipse.statet.r.core.model.IRClass;
import org.eclipse.statet.r.core.model.IRElement;
import org.eclipse.statet.r.core.model.IRMethod;
import org.eclipse.statet.r.core.model.IRSlot;
import org.eclipse.statet.r.core.model.IRSourceUnit;
import org.eclipse.statet.r.ui.RUI;


/**
 * Class that offers access to the code templates contained.
 */
public class CodeGeneration {
	
	
	/**
	 * Generates initial content for a new R script file.
	 * 
	 * @param su the R source unit to create the source for. The unit does not need to exist
	 * @param lineDelimiter the line delimiter to be used
	 * @return the new content or <code>null</code> if the template is undefined or empty
	 * @throws CoreException thrown when the evaluation of the code template fails
	 */
	public static EvaluatedTemplate getNewRFileContent(final IRSourceUnit su, final String lineDelimiter) throws CoreException {
		final Template template = RUIPlugin.getInstance().getRCodeGenerationTemplateStore().findTemplate(RCodeTemplateContextType.NEW_RSCRIPTFILE);
		if (template == null) {
			return null;
		}
		
		final RCodeTemplateContext context = new RCodeTemplateContext(
				RCodeTemplateContextType.NEW_RSCRIPTFILE_CONTEXTTYPE, su, lineDelimiter);
		
		try {
			final TemplateBuffer buffer = context.evaluate(template);
			if (buffer == null) {
				return null;
			}
			return new TemplateUtils.EvaluatedTemplate(buffer, lineDelimiter);
		}
		catch (final Exception e) {
			throw new CoreException(new Status(IStatus.ERROR, RUI.BUNDLE_ID, NLS.bind(
					TemplateMessages.TemplateEvaluation_error_description, template.getDescription()), e));
		}
	}
	
	/**
	 * Generates content for the Roxygen comment for the given function definition
	 * @param rMethod function element
	 * @param lineDelimiter the line delimiter to be used
	 * @return 
	 * @throws CoreException thrown when the evaluation of the code template fails
	 */
	public static EvaluatedTemplate getCommonFunctionRoxygenComment(final IRMethod rMethod, final String lineDelimiter) throws CoreException {
		final Template template = RUIPlugin.getInstance().getRCodeGenerationTemplateStore()
				.findTemplate(RCodeTemplateContextType.ROXYGEN_COMMONFUNCTION_TEMPLATE_ID);
		if (template == null) {
			return null;
		}
		
		final ISourceUnit su = rMethod.getSourceUnit();
		final RCodeTemplateContext context = new RCodeTemplateContext(
				RCodeTemplateContextType.ROXYGEN_COMMONFUNCTION_CONTEXTTYPE, su, lineDelimiter);
		context.setRElement(rMethod);
		
		try {
			final TemplateBuffer buffer = context.evaluate(template);
			if (buffer == null) {
				return null;
			}
			final EvaluatedTemplate data = new EvaluatedTemplate(buffer, lineDelimiter);
			
			final AbstractDocument content = data.startPostEdit();
			final StringBuilder tagBuffer = new StringBuilder(64);
			final TemplateVariable paramVariable = TemplateUtils.findVariable(buffer,
					RCodeTemplateContextType.ROXYGEN_PARAM_TAGS_VAR_NAME );
			final Position[] paramPositions = new Position[(paramVariable != null) ? paramVariable.getOffsets().length : 0];
			for (int i = 0; i < paramPositions.length; i++) {
				paramPositions[i] = new Position(paramVariable.getOffsets()[i], paramVariable.getLength());
				content.addPosition(paramPositions[i]);
			}
			
			if (paramPositions.length > 0) {
				String[] tags = null;
				final ArgsDefinition args = rMethod.getArgsDefinition();
				if (args != null) {
					final int count = args.size();
					tags = new String[count];
					for (int i = 0; i < count; i++) {
						tagBuffer.append("@param "); //$NON-NLS-1$
						tagBuffer.append(args.get(i).name);
						tagBuffer.append(" "); //$NON-NLS-1$
						tags[i] = tagBuffer.toString();
						tagBuffer.setLength(0);
					}
				}
				for (final Position pos : paramPositions) {
					insertRoxygen(content, pos, tags);
				}
			}
			
			data.finishPostEdit();
			return data;
		}
		catch (final Exception e) {
			throw new CoreException(new Status(IStatus.ERROR, RUI.BUNDLE_ID, NLS.bind(
					TemplateMessages.TemplateEvaluation_error_description, template.getDescription()), e));
		}
	}
	
	/**
	 * Generates content for the Roxygen comment for the given class definition
	 * @param rClass class element
	 * @param lineDelimiter the line delimiter to be used
	 * @return 
	 * @throws CoreException thrown when the evaluation of the code template fails
	 */
	public static EvaluatedTemplate getClassRoxygenComment(final IRClass rClass, final String lineDelimiter) throws CoreException {
		final Template template = RUIPlugin.getInstance().getRCodeGenerationTemplateStore()
				.findTemplate(RCodeTemplateContextType.ROXYGEN_S4CLASS_TEMPLATE_ID);
		if (template == null) {
			return null;
		}
		
		final ISourceUnit su = rClass.getSourceUnit();
		final RCodeTemplateContext context = new RCodeTemplateContext(
				RCodeTemplateContextType.ROXYGEN_CLASS_CONTEXTTYPE, su, lineDelimiter);
		context.setRElement(rClass);
		
		try {
			final TemplateBuffer buffer = context.evaluate(template);
			if (buffer == null) {
				return null;
			}
			final EvaluatedTemplate data = new EvaluatedTemplate(buffer, lineDelimiter);
			
			final AbstractDocument content = data.startPostEdit();
			final StringBuilder tagBuffer = new StringBuilder(64);
			final TemplateVariable slotVariable = TemplateUtils.findVariable(buffer,
					RCodeTemplateContextType.ROXYGEN_SLOT_TAGS_VAR_NAME );
			final Position[] slotPositions = new Position[(slotVariable != null) ? slotVariable.getOffsets().length : 0];
			for (int i = 0; i < slotPositions.length; i++) {
				slotPositions[i] = new Position(slotVariable.getOffsets()[i], slotVariable.getLength());
				content.addPosition(slotPositions[i]);
			}
			
			if (slotPositions.length > 0) {
				String[] tags = null;
				final List<? extends IModelElement> slots = rClass.getModelChildren(IRElement.R_S4SLOT_FILTER);
				final int count = slots.size();
				tags = new String[count];
				for (int i = 0; i < count; i++) {
					final IRSlot slot = (IRSlot) slots.get(i);
					tagBuffer.append("@slot "); //$NON-NLS-1$
					tagBuffer.append(slot.getElementName().getDisplayName());
					tagBuffer.append(" "); //$NON-NLS-1$
					tags[i] = tagBuffer.toString();
					tagBuffer.setLength(0);
				}
				for (final Position pos : slotPositions) {
					insertRoxygen(content, pos, tags);
				}
			}
			
			data.finishPostEdit();
			return data;
		}
		catch (final Exception e) {
			throw new CoreException(new Status(IStatus.ERROR, RUI.BUNDLE_ID, NLS.bind(
					TemplateMessages.TemplateEvaluation_error_description, template.getDescription()), e));
		}
	}
	
	/**
	 * Generates content for the Roxygen comment for the given method definition
	 * @param rMethod function element
	 * @param lineDelimiter the line delimiter to be used
	 * @return 
	 * @throws CoreException thrown when the evaluation of the code template fails
	 */
	public static EvaluatedTemplate getMethodRoxygenComment(final IRMethod rMethod, final String lineDelimiter) throws CoreException {
		final Template template = RUIPlugin.getInstance().getRCodeGenerationTemplateStore()
				.findTemplate(RCodeTemplateContextType.ROXYGEN_S4METHOD_TEMPLATE_ID);
		if (template == null) {
			return null;
		}
		
		final ISourceUnit su = rMethod.getSourceUnit();
		final RCodeTemplateContext context = new RCodeTemplateContext(
				RCodeTemplateContextType.ROXYGEN_METHOD_CONTEXTTYPE, su, lineDelimiter);
		context.setRElement(rMethod);
		
		try {
			final TemplateBuffer buffer = context.evaluate(template);
			if (buffer == null) {
				return null;
			}
			final EvaluatedTemplate data = new EvaluatedTemplate(buffer, lineDelimiter);
			
			final AbstractDocument content = data.startPostEdit();
			final StringBuilder sb = new StringBuilder(64);
			
			final Position[] sigPositions;
			String sigText = null;
			{	final TemplateVariable variable = TemplateUtils.findVariable(buffer,
						RCodeTemplateContextType.ROXYGEN_SIG_LIST_VAR_NAME );
				sigPositions = new Position[(variable != null) ? variable.getOffsets().length : 0];
				for (int i = 0; i < sigPositions.length; i++) {
					sigPositions[i] = new Position(variable.getOffsets()[i], variable.getLength());
					content.addPosition(sigPositions[i]);
				}
				
				if (sigPositions.length > 0) {
					final ArgsDefinition args = rMethod.getArgsDefinition();
					if (args != null) {
						final int count = args.size();
						for (int i = 0; i < count; i++) {
							final Arg arg = args.get(i);
							if (arg.className == null || arg.className.equals("ANY")) { //$NON-NLS-1$
								break;
							}
							sb.append(arg.className);
							sb.append(","); //$NON-NLS-1$
						}
						if (sb.length() > 0) {
							sigText = sb.substring(0, sb.length()-1);
							sb.setLength(0);
						}
					}
				}
			}
			final Position[] paramPositions;
			String[] paramTags = null;
			{	final TemplateVariable variable = TemplateUtils.findVariable(buffer,
						RCodeTemplateContextType.ROXYGEN_PARAM_TAGS_VAR_NAME );
				paramPositions = new Position[(variable != null) ? variable.getOffsets().length : 0];
				for (int i = 0; i < paramPositions.length; i++) {
					paramPositions[i] = new Position(variable.getOffsets()[i], variable.getLength());
					content.addPosition(paramPositions[i]);
				}
				
				if (paramPositions.length > 0) {
					final ArgsDefinition args = rMethod.getArgsDefinition();
					if (args != null) {
						final int count = args.size();
						paramTags = new String[count];
						for (int i = 0; i < count; i++) {
							sb.append("@param "); //$NON-NLS-1$
							sb.append(args.get(i).name);
							sb.append(" "); //$NON-NLS-1$
							paramTags[i] = sb.toString();
							sb.setLength(0);
						}
					}
				}
			}
			
			for (final Position pos : sigPositions) {
				insertRoxygen(content, pos, sigText);
			}
			for (final Position pos : paramPositions) {
				insertRoxygen(content, pos, paramTags);
			}
			
			data.finishPostEdit();
			return data;
		}
		catch (final Exception e) {
			throw new CoreException(new Status(IStatus.ERROR, RUI.BUNDLE_ID, NLS.bind(
					TemplateMessages.TemplateEvaluation_error_description, template.getDescription()), e));
		}
	}
	
	/**
	 * Generates initial content for a new Rd file.
	 * 
	 * @param su the Rd source unit to create the source for. The unit does not need to exist
	 * @param lineDelimiter the line delimiter to be used
	 * @return the new content or <code>null</code> if the template is undefined or empty
	 * @throws CoreException thrown when the evaluation of the code template fails
	 */
	public static EvaluatedTemplate getNewRdFileContent(final RResourceUnit su, final String lineDelimiter) throws CoreException {
		final Template template = RUIPlugin.getInstance().getRdCodeGenerationTemplateStore().findTemplate(RdCodeTemplateContextType.NEW_RDOCFILE);
		if (template == null) {
			return null;
		}
		
		final RdCodeTemplateContext context = new RdCodeTemplateContext(
				RdCodeTemplateContextType.NEW_RDOCFILE_CONTEXTTYPE, su, lineDelimiter);
		
		try {
			final TemplateBuffer buffer = context.evaluate(template);
			if (buffer == null) {
				return null;
			}
			return new TemplateUtils.EvaluatedTemplate(buffer, lineDelimiter);
		}
		catch (final Exception e) {
			throw new CoreException(new Status(IStatus.ERROR, RUI.BUNDLE_ID, NLS.bind(
					TemplateMessages.TemplateEvaluation_error_description, template.getDescription()), e));
		}
	}
	
	private static void insertRoxygen(final AbstractDocument doc, final Position pos, final String[] tags) throws BadLocationException {
		final int line = doc.getLineOfOffset(pos.getOffset());
		final int lineOffset = doc.getLineOffset(line);
		final int lineLength = doc.getLineLength(line);
		
		final String orgLine = doc.get(lineOffset, lineLength);
		final String prefix = orgLine.substring(0, pos.getOffset()-lineOffset); // can be replaced by more intelligent search
		if (tags == null) {
			return;
		}
		if (tags.length == 0) {
			if (onlyWhitespace(orgLine.substring(prefix.length(), pos.getOffset()-lineOffset))
					&& onlyWhitespace(orgLine.substring(pos.getOffset()-lineOffset+pos.getLength()))) {
				doc.replace(lineOffset, lineLength, ""); //$NON-NLS-1$
				return;
			}
			else {
				doc.replace(pos.getOffset(), pos.getLength(), ""); //$NON-NLS-1$
				return;
			}
		}
		final StringBuilder sb = new StringBuilder(tags.length * 16);
		sb.append(tags[0]);
		for (int i = 1; i < tags.length; i++) {
			sb.append(doc.getDefaultLineDelimiter());
			sb.append(prefix);
			sb.append(tags[i]);
		}
		doc.replace(pos.getOffset(), pos.getLength(), sb.toString());
	}
	
	private static void insertRoxygen(final AbstractDocument doc, final Position pos, final String s) throws BadLocationException {
		doc.replace(pos.getOffset(), pos.getLength(), (s != null) ? s : ""); //$NON-NLS-1$
	}
	
	private static boolean onlyWhitespace(final String s) {
		for (int i = 0; i < s.length(); i++) {
			final char c = s.charAt(0);
			if (c != ' ' && c != '\t' && c != '\n' && c != '\r') {
				return false;
			}
		}
		return true;
	}
	
	
	private CodeGeneration() {}
	
}
