/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.javaeditor;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.ResourceBundle;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.swt.SWTError;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.RTFTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.jface.viewers.ISelection;

import org.eclipse.jface.text.Assert;
import org.eclipse.jface.text.IRewriteTarget;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Region;

import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
import org.eclipse.ui.texteditor.TextEditorAction;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;

import org.eclipse.jdt.internal.corext.codemanipulation.ImportReferencesCollector;
import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;

import org.eclipse.jdt.ui.PreferenceConstants;

import org.eclipse.jdt.internal.ui.JavaPlugin;


/**
 * Action for cut/copy and paste with support for adding imports on paste.
 */
public final class ClipboardOperationAction extends TextEditorAction {

	public static class ClipboardData {
		private String fOriginHandle;
		private String[] fTypeImports;
		private String[] fStaticImports;

		public ClipboardData(IJavaElement origin, String[] typeImports, String[] staticImports) {
			Assert.isNotNull(origin);
			Assert.isNotNull(typeImports);
			Assert.isNotNull(staticImports);

			fTypeImports= typeImports;
			fStaticImports= staticImports;
			fOriginHandle= origin.getHandleIdentifier();
		}

		public ClipboardData(byte[] bytes) throws IOException {
			DataInputStream dataIn = new DataInputStream(new ByteArrayInputStream(bytes));
			try {
				fOriginHandle= dataIn.readUTF();
				fTypeImports= readArray(dataIn);
				fStaticImports= readArray(dataIn);
			} finally {
				dataIn.close();
			}
		}

		private static String[] readArray(DataInputStream dataIn) throws IOException {
			int count= dataIn.readInt();

			String[] array= new String[count];
			for (int i = 0; i < count; i++) {
				array[i]= dataIn.readUTF();
			}
			return array;
		}

		private static void writeArray(DataOutputStream dataOut, String[] array) throws IOException {
			dataOut.writeInt(array.length);
			for (int i = 0; i < array.length; i++) {
				dataOut.writeUTF(array[i]);
			}
		}

		public String[] getTypeImports() {
			return fTypeImports;
		}

		public String[] getStaticImports() {
			return fStaticImports;
		}

		public boolean isFromSame(IJavaElement elem) {
			return fOriginHandle.equals(elem.getHandleIdentifier());
		}

		public byte[] serialize() throws IOException {
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			DataOutputStream dataOut = new DataOutputStream(out);
			try {
				dataOut.writeUTF(fOriginHandle);
				writeArray(dataOut, fTypeImports);
				writeArray(dataOut, fStaticImports);
			} finally {
				dataOut.close();
				out.close();
			}

			return out.toByteArray();
		}
	}


	private static class ClipboardTransfer extends ByteArrayTransfer {

		private static final String TYPE_NAME = "source-with-imports-transfer-format" + System.currentTimeMillis(); //$NON-NLS-1$

		private static final int TYPEID = registerType(TYPE_NAME);

		/* (non-Javadoc)
		 * @see org.eclipse.swt.dnd.Transfer#getTypeIds()
		 */
		protected int[] getTypeIds() {
			return new int[] { TYPEID };
		}

		/* (non-Javadoc)
		 * @see org.eclipse.swt.dnd.Transfer#getTypeNames()
		 */
		protected String[] getTypeNames() {
			return new String[] { TYPE_NAME };
		}

		/* (non-Javadoc)
		 * @see org.eclipse.swt.dnd.Transfer#javaToNative(java.lang.Object, org.eclipse.swt.dnd.TransferData)
		 */
		protected void javaToNative(Object data, TransferData transferData) {
			if (data instanceof ClipboardData) {
				try {
					super.javaToNative(((ClipboardData) data).serialize(), transferData);
				} catch (IOException e) {
					//it's best to send nothing if there were problems
				}
			}
		}

		/* (non-Javadoc)
		 * Method declared on Transfer.
		 */
		protected Object nativeToJava(TransferData transferData) {
			byte[] bytes = (byte[]) super.nativeToJava(transferData);
			if (bytes != null) {
				try {
					return new ClipboardData(bytes);
				} catch (IOException e) {
				}
			}
			return null;
		}

	}

	private static final ClipboardTransfer fgTransferInstance = new ClipboardTransfer();

	/** The text operation code */
	private int fOperationCode= -1;
	/** The text operation target */
	private ITextOperationTarget fOperationTarget;


	/**
	 * Creates the action.
	 */
	public ClipboardOperationAction(ResourceBundle bundle, String prefix, ITextEditor editor, int operationCode) {
		super(bundle, prefix, editor);
		fOperationCode= operationCode;

		if (operationCode == ITextOperationTarget.CUT) {
			setHelpContextId(IAbstractTextEditorHelpContextIds.CUT_ACTION);
			setActionDefinitionId(IWorkbenchActionDefinitionIds.CUT);
		} else if (operationCode == ITextOperationTarget.COPY) {
			setHelpContextId(IAbstractTextEditorHelpContextIds.COPY_ACTION);
			setActionDefinitionId(IWorkbenchActionDefinitionIds.COPY);
		} else if (operationCode == ITextOperationTarget.PASTE) {
			setHelpContextId(IAbstractTextEditorHelpContextIds.PASTE_ACTION);
			setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE);
		} else {
			Assert.isTrue(false, "Invalid operation code"); //$NON-NLS-1$
		}
		update();
	}

	private boolean isReadOnlyOperation() {
		return fOperationCode == ITextOperationTarget.COPY;
	}


	/* (non-Javadoc)
	 * @see org.eclipse.jface.action.IAction#run()
	 */
	public void run() {
		if (fOperationCode == -1 || fOperationTarget == null)
			return;

		ITextEditor editor= getTextEditor();
		if (editor == null)
			return;

		if (!isReadOnlyOperation() && !validateEditorInputState())
			return;

		BusyIndicator.showWhile(getDisplay(), new Runnable() {
			public void run() {
				internalDoOperation();
			}
		});
	}

	private Shell getShell() {
		ITextEditor editor= getTextEditor();
		if (editor != null) {
			IWorkbenchPartSite site= editor.getSite();
			Shell shell= site.getShell();
			if (shell != null && !shell.isDisposed()) {
				return shell;
			}
		}
		return null;
	}

	private Display getDisplay() {
		Shell shell= getShell();
		if (shell != null) {
			return shell.getDisplay();
		}
		return null;
	}


	protected final void internalDoOperation() {
		if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_IMPORTS_ON_PASTE)) {
			if (fOperationCode == ITextOperationTarget.PASTE) {
				doPasteWithImportsOperation();
			} else {
				doCutCopyWithImportsOperation();
			}
		} else {
			fOperationTarget.doOperation(fOperationCode);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.IUpdate#update()
	 */
	public void update() {
		super.update();

		if (!isReadOnlyOperation() && !canModifyEditor()) {
			setEnabled(false);
			return;
		}

		ITextEditor editor= getTextEditor();
		if (fOperationTarget == null && editor!= null && fOperationCode != -1)
			fOperationTarget= (ITextOperationTarget) editor.getAdapter(ITextOperationTarget.class);

		boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode));
		setEnabled(isEnabled);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.texteditor.TextEditorAction#setEditor(org.eclipse.ui.texteditor.ITextEditor)
	 */
	public void setEditor(ITextEditor editor) {
		super.setEditor(editor);
		fOperationTarget= null;
	}


	private void doCutCopyWithImportsOperation() {
		ITextEditor editor= getTextEditor();
		IJavaElement inputElement= (IJavaElement) editor.getEditorInput().getAdapter(IJavaElement.class);
		ISelection selection= editor.getSelectionProvider().getSelection();

		Object clipboardData= null;
		if (inputElement != null && selection instanceof ITextSelection && !selection.isEmpty()) {
			ITextSelection textSelection= (ITextSelection) selection;
			if (isNonTrivialSelection(textSelection)) {
				clipboardData= getClipboardData(inputElement, textSelection.getOffset(), textSelection.getLength());
			}
		}

		fOperationTarget.doOperation(fOperationCode);

		if (clipboardData != null) {
			Clipboard clipboard= new Clipboard(getDisplay());
			try {
				/*
				 * We currently make assumptions about what the styled text widget sets,
				 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=61876
				 */
				Object textData= clipboard.getContents(TextTransfer.getInstance());
				Object rtfData= clipboard.getContents(RTFTransfer.getInstance());

				ArrayList datas= new ArrayList(3);
				ArrayList transfers= new ArrayList(3);
				if (textData != null) {
					datas.add(textData);
					transfers.add(TextTransfer.getInstance());
				}
				if (rtfData != null) {
					datas.add(rtfData);
					transfers.add(RTFTransfer.getInstance());
				}

				/*
				 * Don't add if we didn't get any data from the clipboard
				 * see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=70077
				 */
				if (datas.isEmpty())
					return;

				datas.add(clipboardData);
				transfers.add(fgTransferInstance);

				Transfer[] dataTypes= (Transfer[]) transfers.toArray(new Transfer[transfers.size()]);
				Object[] data= datas.toArray();
				setClipboardContents(clipboard, data, dataTypes);
			} finally {
				clipboard.dispose();
			}
		}
	}

	private void setClipboardContents(Clipboard clipboard, Object[] datas, Transfer[] transfers) {
		try {
			clipboard.setContents(datas, transfers);
		} catch (SWTError e) {
			if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) {
				throw e;
			}
			// silently fail.  see e.g. https://bugs.eclipse.org/bugs/show_bug.cgi?id=65975
		}
	}

	private boolean isNonTrivialSelection(ITextSelection selection) {
		if (selection.getLength() < 30) {
			String text= selection.getText();
			if (text != null) {
				for (int i= 0; i < text.length(); i++) {
					if (!Character.isJavaIdentifierPart(text.charAt(i))) {
						return true;
					}
				}
			}
			return false;
		}
		return true;
	}


	private ClipboardData getClipboardData(IJavaElement inputElement, int offset, int length) {
		CompilationUnit astRoot= JavaPlugin.getDefault().getASTProvider().getAST(inputElement, ASTProvider.WAIT_ACTIVE_ONLY, null);
		if (astRoot == null) {
			return null;
		}

		// do process import if selection spans over import declaration or package
		List list= astRoot.imports();
		if (!list.isEmpty()) {
			if (offset < ((ASTNode) list.get(list.size() - 1)).getStartPosition()) {
				return null;
			}
		} else if (astRoot.getPackage() != null) {
			if (offset < ((ASTNode) astRoot.getPackage()).getStartPosition()) {
				return null;
			}
		}

		ArrayList typeImportsRefs= new ArrayList();
		ArrayList staticImportsRefs= new ArrayList();

		ImportReferencesCollector.collect(astRoot, inputElement.getJavaProject(), new Region(offset, length), typeImportsRefs, staticImportsRefs);

		if (typeImportsRefs.isEmpty() && staticImportsRefs.isEmpty()) {
			return null;
		}

		HashSet namesToImport= new HashSet(typeImportsRefs.size());
		for (int i= 0; i < typeImportsRefs.size(); i++) {
			Name curr= (Name) typeImportsRefs.get(i);
			IBinding binding= curr.resolveBinding();
			if (binding != null && binding.getKind() == IBinding.TYPE) {
				ITypeBinding typeBinding= (ITypeBinding) binding;
				if (typeBinding.isArray()) {
					typeBinding= typeBinding.getElementType();
				}
				if (typeBinding.isTypeVariable() || typeBinding.isCapture() || typeBinding.isWildcardType()) { // can be removed when bug 98473 is fixed
					continue; 
				}
				
				if (typeBinding.isMember() || typeBinding.isTopLevel()) {
					String name= Bindings.getRawQualifiedName(typeBinding);
					if (name.length() > 0) {
						namesToImport.add(name);
					}
				}
			}
		}

		HashSet staticsToImport= new HashSet(staticImportsRefs.size());
		for (int i= 0; i < staticImportsRefs.size(); i++) {
			Name curr= (Name) staticImportsRefs.get(i);
			IBinding binding= curr.resolveBinding();
			if (binding != null) {
				StringBuffer buf= new StringBuffer(Bindings.getImportName(binding));
				if (binding.getKind() == IBinding.METHOD) {
					buf.append("()"); //$NON-NLS-1$
				}
				staticsToImport.add(buf.toString());
			}
		}


		if (namesToImport.isEmpty() && staticsToImport.isEmpty()) {
			return null;
		}

		String[] typeImports= (String[]) namesToImport.toArray(new String[namesToImport.size()]);
		String[] staticImports= (String[]) staticsToImport.toArray(new String[staticsToImport.size()]);
		return new ClipboardData(inputElement, typeImports, staticImports);
	}


	private void doPasteWithImportsOperation() {
		ITextEditor editor= getTextEditor();
		IJavaElement inputElement= (IJavaElement) editor.getEditorInput().getAdapter(IJavaElement.class);

		Clipboard clipboard= new Clipboard(getDisplay());
		ClipboardData importsData= (ClipboardData) clipboard.getContents(fgTransferInstance);
		if (importsData != null && inputElement instanceof ICompilationUnit && !importsData.isFromSame(inputElement)) {
			// combine operation and adding of imports
			IRewriteTarget target= editor != null ? (IRewriteTarget) editor.getAdapter(IRewriteTarget.class) : null;
			if (target != null) {
				target.beginCompoundChange();
			}
			try {
				fOperationTarget.doOperation(fOperationCode);
				addImports((ICompilationUnit) inputElement, importsData);
			} catch (CoreException e) {
				JavaPlugin.log(e);
			} finally {
				if (target != null) {
					target.endCompoundChange();
				}
			}
		} else {
			fOperationTarget.doOperation(fOperationCode);
		}
	}


	private void addImports(ICompilationUnit unit, ClipboardData data) throws CoreException {
		ImportRewrite rewrite= StubUtility.createImportRewrite(unit, true);
		String[] imports= data.getTypeImports();
		for (int i= 0; i < imports.length; i++) {
			rewrite.addImport(imports[i]);
		}
		String[] staticImports= data.getStaticImports();
		for (int i= 0; i < staticImports.length; i++) {
			String name= Signature.getSimpleName(staticImports[i]);
			boolean isField= !name.endsWith("()"); //$NON-NLS-1$
			if (!isField) {
				name= name.substring(0, name.length() - 2);
			}
			String qualifier= Signature.getQualifier(staticImports[i]);
			rewrite.addStaticImport(qualifier, name, isField);
		}

		JavaModelUtil.applyEdit(unit, rewrite.rewriteImports(null), false, null);
	}


}
