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

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;

import org.eclipse.statet.ecommons.ui.workbench.WorkbenchUIUtils;

import org.eclipse.statet.internal.ltk.ui.EditingMessages;
import org.eclipse.statet.ltk.model.core.ElementSet;
import org.eclipse.statet.ltk.model.core.elements.ISourceStructElement;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditorAssociated;
import org.eclipse.statet.ltk.ui.util.LTKSelectionUtils;


public abstract class AbstractSourceDocumentHandler<TSourceUnit extends ISourceUnit>
		extends AbstractHandler {
	
	
	protected class ExecData {
		
		private final IWorkbenchPart activePart;
		private final ISourceEditor sourceEditor;
		private final ImList<? extends TSourceUnit> sourceUnits;
		
		final ITextSelection textSelection;
		
		final ElementSet elementSelection;
		
		
		public ExecData(final IWorkbenchPart activePart, final ISourceEditor sourceEditor,
				final ImList<? extends TSourceUnit> sourceUnits,
				final ITextSelection textSelection, final ElementSet elementSet) {
			this.activePart= activePart;
			this.sourceEditor= sourceEditor;
			this.sourceUnits= sourceUnits;
			
			this.textSelection= textSelection;
			this.elementSelection= elementSet;
		}
		
		public IWorkbenchPart getActivePart() {
			return this.activePart;
		}
		
		public ISourceEditor getSourceEditor() {
			return this.sourceEditor;
		}
		
		public ImList<? extends TSourceUnit> getSourceUnits() {
			return this.sourceUnits;
		}
		
		public ITextSelection getTextSelection() {
			return this.textSelection;
		}
		
		public ElementSet getElementSelection() {
			return this.elementSelection;
		}
		
	}
	
	protected static final byte DIRECT= 0;
	protected static final byte SHOW_BUSY= 1;
	protected static final byte BACKGROUND= 2;
	
	
	public AbstractSourceDocumentHandler() {
	}
	
	
	protected abstract String getTaskLabel();
	
	protected abstract boolean isEditTask();
	
	
	@Override
	public void setEnabled(final Object evaluationContext) {
		final IWorkbenchPart activePart= WorkbenchUIUtils.getActivePart(evaluationContext);
		final ISelection selection= WorkbenchUIUtils.getCurrentSelection(evaluationContext);
		final ISourceEditor sourceEditor= getSourceEditor(activePart);
		
		if (sourceEditor != null && selection instanceof ITextSelection) {
			final ISourceUnit sourceUnit= sourceEditor.getSourceUnit();
			setBaseEnabled(sourceUnit != null &&
					(!isEditTask() || sourceEditor.isEditable(false) ));
			return;
		}
		
		if (selection instanceof IStructuredSelection) {
			final ISourceStructElement[] selectedElements= LTKSelectionUtils
					.getSelectedSourceStructElements((IStructuredSelection) selection);
			setBaseEnabled(selectedElements != null && selectedElements.length > 0
					&& checkSourceUnits(selectedElements) );
			return;
		}
		
		setBaseEnabled(false);
	}
	
	@Override
	public Object execute(final ExecutionEvent event) throws ExecutionException {
		final IWorkbenchPart activePart= WorkbenchUIUtils.getActivePart(event.getApplicationContext());
		final ISelection selection= WorkbenchUIUtils.getCurrentSelection(event.getApplicationContext());
		final ISourceEditor sourceEditor= getSourceEditor(activePart);
		
		try {
			final IProgressMonitor monitor= new NullProgressMonitor();
			if (sourceEditor != null && selection instanceof ITextSelection) {
				final ISourceUnit sourceUnit= sourceEditor.getSourceUnit();
				if (sourceUnit != null && isSourceUnitSupported(sourceUnit)) {
					if (!isEditTask() || sourceEditor.isEditable(true)) {
						final ExecData data= createExecData(event, activePart, sourceEditor,
								ImCollections.newList((TSourceUnit) sourceUnit),
								(ITextSelection) selection, null, monitor );
						if (data != null) {
							execute(data);
							return null;
						}
					}
				}
				return null;
			}
			if (selection instanceof IStructuredSelection) {
				final ISourceStructElement[] selectedElements= LTKSelectionUtils
						.getSelectedSourceStructElements((IStructuredSelection) selection);
				if (selectedElements != null && selectedElements.length > 0) {
					final ImList<TSourceUnit> sourceUnits= createSourceUnits(selectedElements, monitor);
					if (sourceUnits != null) {
						final ExecData data= createExecData(event, activePart, sourceEditor,
								sourceUnits, null, selectedElements, monitor );
						if (data != null) {
							execute(data);
							return null;
						}
					}
				}
				return null;
			}
			return null;
		}
		catch (final Exception e) {
			throw new ExecutionException(
					NLS.bind(EditingMessages.GenericAction_error_message, getTaskLabel()),
					e );
		}
	}
	
	private ISourceEditor getSourceEditor(final IWorkbenchPart part) {
		if (part instanceof ISourceEditor) {
			return (ISourceEditor) part;
		}
		{	final ISourceEditor editor= part.getAdapter(ISourceEditor.class);
			if (editor != null) {
				return editor;
			}
		}
		{	final ISourceEditorAssociated editorAssociated= part
					.getAdapter(ISourceEditorAssociated.class);
			if (editorAssociated != null) {
				return editorAssociated.getSourceEditor();
			}
		}
		return null;
	}
	
	private boolean checkSourceUnits(final ISourceStructElement[] selectedElements) {
		ISourceUnit lastSourceUnit= null;
		List<ISourceUnit> sourceUnits= null;
		for (int i= 0; i < selectedElements.length; i++) {
			final ISourceUnit sourceUnit= selectedElements[i].getSourceUnit();
			if (sourceUnit == null) {
				return false;
			}
			if (sourceUnit.equals(lastSourceUnit)
					|| (sourceUnits != null && sourceUnits.contains(sourceUnit)) ) {
				continue;
			}
			if (!isSourceUnitSupported(sourceUnit)
					|| (isEditTask() && !sourceUnit.checkState(false, null)) ) {
				return false;
			}
			if (lastSourceUnit == null) {
				lastSourceUnit= sourceUnit;
			}
			else {
				if (sourceUnits == null) {
					if (!isMultiSourceUnitsSupported()) {
						return false;
					}
					sourceUnits= new ArrayList<>();
					sourceUnits.add(lastSourceUnit);
				}
				sourceUnits.add(sourceUnit);
				lastSourceUnit= sourceUnit;
			}
		}
		return true;
	}
	
	private ImList<TSourceUnit> createSourceUnits(final ISourceStructElement[] selectedElements,
			final IProgressMonitor monitor) {
		TSourceUnit lastSourceUnit= null;
		List<TSourceUnit> sourceUnits= null;
		for (int i= 0; i < selectedElements.length; i++) {
			final ISourceUnit sourceUnit= selectedElements[i].getSourceUnit();
			if (sourceUnit == null) {
				return null;
			}
			if (sourceUnit.equals(lastSourceUnit)
					|| (sourceUnits != null && sourceUnits.contains(sourceUnit)) ) {
				continue;
			}
			if (!isSourceUnitSupported(sourceUnit)
					|| (isEditTask() && !sourceUnit.checkState(true, monitor)) ) {
				return null;
			}
			if (lastSourceUnit == null) {
				lastSourceUnit= (TSourceUnit) sourceUnit;
			}
			else {
				if (sourceUnits == null) {
					if (!isMultiSourceUnitsSupported()) {
						return null;
					}
					sourceUnits= new ArrayList<>();
					sourceUnits.add(lastSourceUnit);
				}
				sourceUnits.add((TSourceUnit) sourceUnit);
				lastSourceUnit= (TSourceUnit) sourceUnit;
			}
		}
		return (sourceUnits == null) ?
				ImCollections.newList(lastSourceUnit) :
				ImCollections.toList(sourceUnits);
	}
	
	private void execute(final ExecData data) throws Exception {
		final AtomicReference<Exception> error= new AtomicReference<>();
		switch (getExecMode(data)) {
		case BACKGROUND:
			try {
				PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
					@Override
					public void run(final IProgressMonitor monitor)
							throws InvocationTargetException, InterruptedException {
						try {
							AbstractSourceDocumentHandler.this.doExecute(data, monitor);
						}
						catch (final Exception e) {
							throw new InvocationTargetException(e);
						}
					}
				});
			}
			catch (final InvocationTargetException e) {
				error.set((Exception) e.getTargetException());
			}
			catch (final InterruptedException e) {}
			break;
		case SHOW_BUSY:
			BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {
				@Override
				public void run() {
					try {
						AbstractSourceDocumentHandler.this.doExecute(data, new NullProgressMonitor());
					}
					catch (final Exception e) {
						error.set(e);
					}
				}
			});
			break;
		default:
			doExecute(data, new NullProgressMonitor());
			return;
		}
		
		if (error.get() != null) {
			throw error.get();
		}
	}
	
	
	protected abstract boolean isSourceUnitSupported(final ISourceUnit sourceUnit);
	
	protected boolean isMultiSourceUnitsSupported() {
		return false;
	}
	
	protected ExecData createExecData(final ExecutionEvent event, final IWorkbenchPart activePart,
			final ISourceEditor sourceEditor, final ImList<? extends TSourceUnit> sourceUnits,
			final ITextSelection textSelection, final ISourceStructElement[] selectedElements,
			final IProgressMonitor monitor) throws Exception {
		return new ExecData(activePart, sourceEditor, sourceUnits, textSelection,
				(selectedElements != null) ? new ElementSet(selectedElements) : null );
	}
	
	protected byte getExecMode(final ExecData data) {
		return (isEditTask()) ? SHOW_BUSY : DIRECT;
	}
	
	protected abstract void doExecute(ExecData data,
			IProgressMonitor monitor) throws Exception;
	
}
