/*******************************************************************************
 * Copyright (c) 2004 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.wst.jsdt.web.ui.internal.java.refactoring;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.DocumentChange;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.osgi.util.NLS;
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.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.wst.jsdt.core.IJavaElement;
import org.eclipse.wst.jsdt.core.search.SearchDocument;
import org.eclipse.wst.jsdt.core.search.SearchMatch;
import org.eclipse.wst.jsdt.core.search.SearchRequestor;
import org.eclipse.wst.jsdt.web.core.internal.java.search.JSDTSearchDocumentDelegate;
import org.eclipse.wst.jsdt.web.core.internal.java.search.JsSearchSupport;
import org.eclipse.wst.jsdt.web.ui.internal.JsUIMessages;
import org.eclipse.wst.jsdt.web.ui.internal.Logger;
import org.eclipse.wst.sse.core.internal.document.DocumentReader;
import org.eclipse.wst.sse.core.internal.encoding.CodedStreamCreator;

/**
 * Creates document change(s) for an IJavaElement rename. Changes are created
 * for every type "match" in the workspace
 * 
 * @author pavery
 */
public class BasicRefactorSearchRequestor extends SearchRequestor {
	/**
	 * Change class that wraps a text edit on the jsp document
	 */
	private class RenameChange extends DocumentChange {
		private String fDescription = JsUIMessages.BasicRefactorSearchRequestor_0;
		private TextEdit fEdit = null;
		private IDocument fJSPDoc = null;
		private IFile fJSPFile = null;
		
		public RenameChange(IFile jspFile, IDocument jspDoc, TextEdit edit, String description) {
			super(JsUIMessages.BasicRefactorSearchRequestor_6, jspDoc);
			this.fEdit = edit;
			this.fJSPFile = jspFile;
			this.fJSPDoc = jspDoc;
			this.fDescription = description;
		}
		
		
		public Object getModifiedElement() {
			return getElement();
		}
		
		
		public String getName() {
			return this.fDescription;
		}
		
		
		public IDocument getPreviewDocument(IProgressMonitor pm) throws CoreException {
			IDocument copyDoc = new Document(fJSPDoc.get());
			try {
				fEdit.apply(copyDoc);
			} catch (MalformedTreeException e) {
				// ignore
			} catch (BadLocationException e) {
				// ignore
			}
			return copyDoc;
		}
		
		/**
		 * Checks if a document is open in an editor
		 * 
		 * @param jspDoc
		 * @return
		 */
		private boolean isOpenInEditor(IDocument jspDoc) {
			IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
			IWorkbenchWindow w = null;
			for (int i = 0; i < windows.length; i++) {
				w = windows[i];
				IWorkbenchPage page = w.getActivePage();
				if (page != null) {
					IEditorReference[] references = page.getEditorReferences();
					IEditorPart editor = null;
					Object o = null;
					IDocument doc = null;
					for (int j = 0; j < references.length; j++) {
						editor = references[j].getEditor(true);
						// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3764
						// use adapter to get ITextEditor (for things like
						// page designer)
						o = editor.getAdapter(ITextEditor.class);
						if (o != null && o instanceof ITextEditor) {
							doc = ((ITextEditor) o).getDocumentProvider().getDocument(editor.getEditorInput());
							if (doc != null && doc.equals(jspDoc)) {
								return true;
							}
						}
					}
				}
			}
			return false;
		}
		
		
		public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException {
			return new RefactoringStatus();
		}
		
		
		public Change perform(IProgressMonitor pm) throws CoreException {
			RenameChange undoChange = null;
			try {
				if (!isOpenInEditor(this.fJSPDoc)) {
					// apply edit to JSP doc AND save model
					undoChange = new RenameChange(this.fJSPFile, this.fJSPDoc, this.fEdit.apply(fJSPDoc), this.fDescription);
					saveFile(this.fJSPFile, this.fJSPDoc);
				} else {
					// just apply edit to JSP document
					undoChange = new RenameChange(this.fJSPFile, this.fJSPDoc, this.fEdit.apply(fJSPDoc), this.fDescription);
				}
			} catch (MalformedTreeException e) {
				Logger.logException(e);
			} catch (BadLocationException e) {
				Logger.logException(e);
			}
			return undoChange;
		}
		
		/**
		 * Performed in an operation since it modifies resources in the
		 * workspace
		 * 
		 * @param jspDoc
		 * @throws CoreException
		 */
		private void saveFile(IFile jspFile, IDocument jspDoc) {
			SaveJspFileOp op = new SaveJspFileOp(jspFile, jspDoc);
			try {
				op.run(JsSearchSupport.getInstance().getProgressMonitor());
			} catch (InvocationTargetException e) {
				Logger.logException(e);
			} catch (InterruptedException e) {
				Logger.logException(e);
			}
		}
	}
	// end inner class SaveJspFileOp
	/**
	 * Workspace operation to perform save on model for updated documents.
	 * Should only be done on models not open in an editor.
	 */
	private class SaveJspFileOp extends WorkspaceModifyOperation {
		private IDocument fJSPDoc = null;
		private IFile fJSPFile = null;
		
		public SaveJspFileOp(IFile jspFile, IDocument jspDoc) {
			this.fJSPDoc = jspDoc;
			this.fJSPFile = jspFile;
		}
		
		
		protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
			// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=3765
			// save file w/ no intermediate model creation
			CodedStreamCreator codedStreamCreator = new CodedStreamCreator();
			Reader reader = new DocumentReader(this.fJSPDoc);
			codedStreamCreator.set(this.fJSPFile, reader);
			ByteArrayOutputStream codedByteStream = null;
			InputStream codedStream = null;
			try {
				codedByteStream = codedStreamCreator.getCodedByteArrayOutputStream();
				codedStream = new ByteArrayInputStream(codedByteStream.toByteArray());
				if (this.fJSPFile.exists()) {
					this.fJSPFile.setContents(codedStream, true, true, null);
				} else {
					this.fJSPFile.create(codedStream, false, null);
				}
			} catch (CoreException e) {
				Logger.logException(e);
			} catch (IOException e) {
				Logger.logException(e);
			} finally {
				try {
					if (codedByteStream != null) {
						codedByteStream.close();
					}
					if (codedStream != null) {
						codedStream.close();
					}
				} catch (IOException e) {
					// unlikely
				}
			}
		}
	}
	// end inner class RenameChange
	/** The type being renamed (the old type) */
	IJavaElement fElement = null;
	/** The new name of the type being renamed */
	private String fNewName = ""; //$NON-NLS-1$
	/** maps a JSPSearchDocument path -> MultiTextEdit for the java file */
	private HashMap fSearchDocPath2JavaEditMap = null;
	
	public BasicRefactorSearchRequestor(IJavaElement element, String newName) {
		this.fNewName = newName;
		this.fElement = element;
		this.fSearchDocPath2JavaEditMap = new HashMap();
	}
	
	/**
	 * @see org.eclipse.wst.jsdt.core.search.SearchRequestor#acceptSearchMatch(org.eclipse.wst.jsdt.core.search.SearchMatch)
	 */
	
	public void acceptSearchMatch(SearchMatch javaMatch) throws CoreException {
		String matchDocumentPath = javaMatch.getResource().getFullPath().toString();
		SearchDocument searchDoc = JsSearchSupport.getInstance().getSearchDocument(matchDocumentPath);
		if (searchDoc != null && searchDoc instanceof JSDTSearchDocumentDelegate) {
			String renameText = getRenameText((JSDTSearchDocumentDelegate) searchDoc, javaMatch);
			// add it for the correct document
			addJavaEdit(searchDoc.getPath(), new ReplaceEdit(javaMatch.getOffset(), javaMatch.getLength(), renameText));
		}
	}
	
	/**
	 * Adds to the multi edit for a give java document.
	 * 
	 * @param javaDocument
	 * @param javaEdit
	 */
	private void addJavaEdit(String searchDocPath, ReplaceEdit javaEdit) {
		Object o = this.fSearchDocPath2JavaEditMap.get(searchDocPath);
		if (o != null) {
			MultiTextEdit multi = (MultiTextEdit) o;
			multi.addChild(javaEdit);
		} else {
			// use a multi edit so doc position offsets get updated
			// automatically
			// when adding multiple child edits
			MultiTextEdit multi = new MultiTextEdit();
			multi.addChild(javaEdit);
			this.fSearchDocPath2JavaEditMap.put(searchDocPath, multi);
		}
	}
	
	private Change createChange(JSDTSearchDocumentDelegate searchDoc, TextEdit edit) {
		IDocument doc = searchDoc.getJspTranslation().getHtmlDocument();
		String file = searchDoc.getFile().getName();
		String description = getDescription();
		try {
			// document lines are 0 based
			String lineNumber = Integer.toString(doc.getLineOfOffset(edit.getOffset()) + 1);
			description += " " + NLS.bind(JsUIMessages.BasicRefactorSearchRequestor_1, new String[] { file, lineNumber }); //$NON-NLS-1$
		} catch (BadLocationException e) {
			Logger.logException(e);
		}
		return new RenameChange(searchDoc.getFile(), doc, edit, description);
	}
	
	/**
	 * 
	 * @return all JSP changes for the search matches for the given Type
	 */
	public Change[] getChanges() {
		JsSearchSupport support = JsSearchSupport.getInstance();
		List changes = new ArrayList();
		Iterator keys = fSearchDocPath2JavaEditMap.keySet().iterator();
		String searchDocPath = null;
		SearchDocument delegate = null;
		while (keys.hasNext()) {
			// create on the fly
			searchDocPath = (String) keys.next();
			MultiTextEdit javaEdit = (MultiTextEdit) fSearchDocPath2JavaEditMap.get(searchDocPath);
			delegate = support.getSearchDocument(searchDocPath);
			if (delegate != null && delegate instanceof JSDTSearchDocumentDelegate) {
				JSDTSearchDocumentDelegate javaDelegate = (JSDTSearchDocumentDelegate) delegate;
				changes.add(createChange(javaDelegate, javaEdit));
			}
		}
		return (Change[]) changes.toArray(new Change[changes.size()]);
	}
	
	/**
	 * Subclasses should override to better describe the change.
	 * 
	 * @return
	 */
	protected String getDescription() {
		return ""; //$NON-NLS-1$
	}
	
	public IJavaElement getElement() {
		return this.fElement;
	}
	
	/**
	 * @return the new name for the Type
	 */
	public String getNewName() {
		return this.fNewName;
	}
	
	/**
	 * @param searchDoc
	 * @return
	 */
	protected String getRenameText(JSDTSearchDocumentDelegate searchDoc, SearchMatch javaMatch) {
		return getNewName();
	}
}