/*******************************************************************************
 * 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.core.internal.java;

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

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.wst.jsdt.core.IBuffer;
import org.eclipse.wst.jsdt.core.ICompilationUnit;
import org.eclipse.wst.jsdt.core.IJavaElement;
import org.eclipse.wst.jsdt.core.IJavaProject;
import org.eclipse.wst.jsdt.core.IPackageDeclaration;
import org.eclipse.wst.jsdt.core.IPackageFragmentRoot;
import org.eclipse.wst.jsdt.core.ISourceRange;
import org.eclipse.wst.jsdt.core.JavaModelException;
import org.eclipse.wst.jsdt.core.LibrarySuperType;
import org.eclipse.wst.jsdt.core.WorkingCopyOwner;
import org.eclipse.wst.jsdt.internal.core.DocumentContextFragmentRoot;
import org.eclipse.wst.jsdt.internal.core.SourceRefElement;
import org.eclipse.wst.jsdt.web.core.internal.Logger;
import org.eclipse.wst.jsdt.web.core.internal.project.JsWebNature;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

/**
 * @author brad childs
 */
public class JsTranslation implements IJsTranslation {
	
	private static final boolean DEBUG;
	static {
		String value = Platform.getDebugOption("org.eclipse.wst.jsdt.web.core/debug/jsptranslation"); //$NON-NLS-1$
		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
	}
	
	private ICompilationUnit fCompilationUnit = null;
	private DocumentContextFragmentRoot fDocumentScope;
	private IJavaProject fJavaProject = null;
	private byte[] fLock = null;
	private IProgressMonitor fProgressMonitor = null;
	private IStructuredDocument fHtmlDocument;
	private String fModelBaseLocation;
	
	
	private static final String SUPER_TYPE_NAME = "Window";
	private static final String SUPER_TYPE_LIBRARY = "org.eclipse.wst.jsdt.launching.baseBrowserLibrary";
	
	private JsTranslator translator;
	
	private String mangledName;
	
	public JsTranslation(IStructuredDocument htmlDocument, IJavaProject javaProj) {
		fLock = new byte[0];
		fJavaProject = javaProj;
		fHtmlDocument = htmlDocument;
		setBaseLocation();
		translator = new JsTranslator(htmlDocument, fModelBaseLocation);
		mangledName = createMangledName();	
	}	
	
	public JsTranslation(IStructuredDocument htmlDocument, IJavaProject javaProj, boolean listenForChanges) {
		fLock = new byte[0];
		fJavaProject = javaProj;
		fHtmlDocument = htmlDocument;
		setBaseLocation();
		translator = new JsTranslator(htmlDocument, fModelBaseLocation,listenForChanges);
		mangledName = createMangledName();	
	}
	
	public IJavaProject getJavaProject() {
		return fJavaProject;
	}

	private IPackageFragmentRoot getDocScope(boolean reset) {
		if(fDocumentScope==null) {
			IProject project = getJavaProject().getProject();
			IResource absoluteRoot = ((IContainer)getJavaProject().getResource()).findMember( WebRootFinder.getWebContentFolder(fJavaProject.getProject()));
			fDocumentScope = new DocumentContextFragmentRoot(fJavaProject, getFile(), WebRootFinder.getWebContentFolder(fJavaProject.getProject()), WebRootFinder.getServerContextRoot(fJavaProject.getProject()), JsWebNature.VIRTUAL_SCOPE_ENTRY);			fDocumentScope.setIncludedFiles(translator.getRawImports());
			return fDocumentScope;
		}
		
		if(reset) fDocumentScope.setIncludedFiles(translator.getRawImports());
		return fDocumentScope;
	}
	
	private void setBaseLocation() {
		IDOMModel xmlModel=null;
		try {
			xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getExistingModelForRead(fHtmlDocument);
			if(xmlModel==null) {
				xmlModel = (IDOMModel) StructuredModelManager.getModelManager().getModelForRead(fHtmlDocument);
			}
			fModelBaseLocation = xmlModel.getBaseLocation();
		}finally {
			if(xmlModel!=null) xmlModel.releaseFromRead();
		}
	//	return xmlModel;
	}
		
	public IFile getFile() {
			return FileBuffers.getWorkspaceFileAtLocation(new Path(fModelBaseLocation));
	}
		
	
	public IDocument getHtmlDocument() {
		return fHtmlDocument;
	}

	public int getMissingTagStart() {
		return translator.getMissingEndTagRegionStart();
	}
	
	private String getWebRoot() {
		return 	WebRootFinder.getWebContentFolder(fJavaProject.getProject()).toString();
	}
	
	public String getDirectoryUnderRoot() {
		String webRoot = getWebRoot() ;
		IPath projectWebRootPath = getJavaProject().getPath().append(webRoot);
		IPath filePath = new Path(fModelBaseLocation).removeLastSegments(1);
		return filePath.removeFirstSegments(projectWebRootPath.matchingFirstSegments(filePath)).toString();
	}
	
	/**
	 * Originally from ReconcileStepForJava. Creates an ICompilationUnit from
	 * the contents of the JSP document.
	 * 
	 * @return an ICompilationUnit from the contents of the JSP document
	 */
	private ICompilationUnit createCompilationUnit() throws JavaModelException {
		//System.out.println("------------------------- CREATING CU ----------------------------");
		LibrarySuperType superType = new LibrarySuperType(SUPER_TYPE_LIBRARY, fJavaProject, SUPER_TYPE_NAME);
		
		IPackageFragmentRoot root = getDocScope(true);
		//String directoryUnderWebroot = getDirectoryUnderRoot();
		ICompilationUnit cu = root.getPackageFragment("").getCompilationUnit(getMangledName() + JsDataTypes.BASE_FILE_EXTENSION).getWorkingCopy(getWorkingCopyOwner(), getProblemRequestor(), getProgressMonitor());
		//ICompilationUnit cu = fDocumentScope.getDefaultPackageFragment().getCompilationUnit(getMangledName() + JsDataTypes.BASE_FILE_EXTENSION,SUPER_TYPE_NAME).getWorkingCopy(getWorkingCopyOwner(), getProblemRequestor(), getProgressMonitor());
		
		IBuffer buffer;
		try {
			buffer = cu.getBuffer();
		} catch (JavaModelException e) {
			e.printStackTrace();
			buffer = null;
		}
		if (buffer != null) {
			translator.setBuffer(buffer);
		}
		return cu;
	}
	
	public String fixupMangledName(String displayString) {
		if (displayString == null) {
			return null;
		}
		return displayString.replaceAll(getMangledName() + ".js", getHtmlPageName());
	}
	
	public IJavaElement[] getAllElementsInJsRange(int javaPositionStart, int javaPositionEnd) {
		IJavaElement[] EMTPY_RESULT_SET = new IJavaElement[0];
		IJavaElement[] result = EMTPY_RESULT_SET;
		IJavaElement[] allChildren = null;
		try {
			allChildren = getCompilationUnit().getChildren();
		} catch (JavaModelException e) {
		}
		Vector validChildren = new Vector();
		for (int i = 0; i < allChildren.length; i++) {
			if (allChildren[i] instanceof IJavaElement && allChildren[i].getElementType() != IJavaElement.PACKAGE_DECLARATION) {
				ISourceRange range = getJSSourceRangeOf(allChildren[i]);
				if (javaPositionStart <= range.getOffset() && range.getLength() + range.getOffset() <= (javaPositionEnd)) {
					validChildren.add(allChildren[i]);
				} else if (allChildren[i].getElementType() == IJavaElement.TYPE) {
					validChildren.add(allChildren[i]);
				}
			}
		}
		if (validChildren.size() > 0) {
			result = (IJavaElement[]) validChildren.toArray(new IJavaElement[] {});
		}
		if (result == null || result.length == 0) {
			return EMTPY_RESULT_SET;
		}
		return result;
	}
	
	public ICompilationUnit getCompilationUnit() {
		synchronized (fLock) {
			try {
				if (fCompilationUnit == null) {
					fCompilationUnit = createCompilationUnit();
					return fCompilationUnit;
				}
				
			} catch (JavaModelException jme) {
				if (JsTranslation.DEBUG) {
					Logger.logException("error creating JSP working copy... ", jme); //$NON-NLS-1$
				}
			}
			
		}
		getDocScope(true);
		try {
			fCompilationUnit = fCompilationUnit.getWorkingCopy(getWorkingCopyOwner(), getProblemRequestor(), getProgressMonitor());
			//fCompilationUnit.makeConsistent(getProgressMonitor());
		} catch (JavaModelException ex) {
			// TODO Auto-generated catch block
			ex.printStackTrace();
		}
		return fCompilationUnit;
	}
	
	public IJavaElement[] getElementsFromJsRange(int javaPositionStart, int javaPositionEnd) {
		IJavaElement[] EMTPY_RESULT_SET = new IJavaElement[0];
		IJavaElement[] result = EMTPY_RESULT_SET;
		try {
			ICompilationUnit cu = getCompilationUnit();
			if (cu != null) {
				synchronized (fLock) {
					int cuDocLength = cu.getBuffer().getLength();
					int javaLength = javaPositionEnd - javaPositionStart;
					if (cuDocLength > 0 && javaPositionStart >= 0 && javaLength >= 0 && javaPositionEnd <= cuDocLength) {
						result = cu.codeSelect(javaPositionStart, javaLength, getWorkingCopyOwner());
					}
				}
			}
			if (result == null || result.length == 0) {
				return EMTPY_RESULT_SET;
			}
		} catch (JavaModelException x) {
			Logger.logException(x);
		}
		return result;
	}
	
	private String getHtmlPageName() {
		IPath path = new Path(fModelBaseLocation);
		return path.lastSegment();
		
	}

	public String getHtmlText() {
		return fHtmlDocument.get();
	}
	
	public String getJavaPath() {
		//String webRoot = getWebRoot() ;
		//IPackageFragmentRoot root = getDocScope(false);
		//String cuPath = root.getPath().append("/" + getMangledName() + JsDataTypes.BASE_FILE_EXTENSION ).toString();
		//ICompilationUnit cu = getCompilationUnit();
		//IPath realCuPath = cu.getPath();
		IPath rootPath = new Path(fModelBaseLocation).removeLastSegments(1);
		String cuPath = rootPath.append("/" + getMangledName() + JsDataTypes.BASE_FILE_EXTENSION ).toString();
		return cuPath;
	}
	
	public IJavaElement getJsElementAtOffset(int jsOffset) {
		IJavaElement elements = null;
		try {
			elements = getCompilationUnit().getElementAt(jsOffset);
		} catch (JavaModelException e) {
			// TODO Auto-generated catch block
			if (JsTranslation.DEBUG) {
				Logger.logException("error retrieving java elemtnt from compilation unit... ", e); //$NON-NLS-1$
			}
			// }
		}
		return elements;
	}
	
	private ISourceRange getJSSourceRangeOf(IJavaElement element) {
		// returns the offset in html of given element
		ISourceRange range = null;
		if (element instanceof SourceRefElement) {
			try {
				range = ((SourceRefElement) element).getSourceRange();
			} catch (JavaModelException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return range;
	}
	
	public String getJsText() {
		return translator.getJsText();
	}
	
	public String getMangledName() {
		return this.mangledName;
	}
	
	private String createMangledName() {
		return JsNameManglerUtil.mangle(fModelBaseLocation);
	}
	
	/**
	 * 
	 * @return the problem requestor for the CompilationUnit in this
	 *         JSPTranslation
	 */
	private JsProblemRequestor getProblemRequestor() {
		return CompilationUnitHelper.getInstance().getProblemRequestor();
	}
	
	public List getProblems() {
		List problems = getProblemRequestor().getCollectedProblems();
		return problems != null ? problems : new ArrayList();
	}
	
	private IProgressMonitor getProgressMonitor() {
		if (fProgressMonitor == null) {
			fProgressMonitor = new NullProgressMonitor();
		}
		return fProgressMonitor;
	}
	
	public WorkingCopyOwner getWorkingCopyOwner() {
		return CompilationUnitHelper.getInstance().getWorkingCopyOwner();
	}
	
	public boolean ifOffsetInImportNode(int offset) {
		Position[] importRanges = translator.getImportHtmlRanges();
		for (int i = 0; i < importRanges.length; i++) {
			if (importRanges[i].includes(offset)) {
				return true;
			}
		}
		return false;
	}

	public void reconcileCompilationUnit() {
		// if(true) return;
		ICompilationUnit cu = getCompilationUnit();
		if (fCompilationUnit == null) {
			return;
		}
		if (cu != null) {
			try {
				synchronized (fLock) {
					// if(false)
					//cu.makeConsistent(getProgressMonitor());
					cu.reconcile(ICompilationUnit.NO_AST, true, getWorkingCopyOwner(), getProgressMonitor());
				}
			} catch (JavaModelException e) {
				Logger.logException(e);
			}
		}
	}
	

	public void release() {
		if(translator!=null) translator.release();
		synchronized (fLock) {
			if (fCompilationUnit != null) {
				try {
					if (JsTranslation.DEBUG) {
						System.out.println("------------------------------------------------------------------"); //$NON-NLS-1$
						System.out.println("(-) JSPTranslation [" + this + "] discarding CompilationUnit: " + fCompilationUnit); //$NON-NLS-1$ //$NON-NLS-2$
						System.out.println("------------------------------------------------------------------"); //$NON-NLS-1$
					}
					fCompilationUnit.discardWorkingCopy();
				} catch (JavaModelException e) {
					// we're done w/ it anyway
				}
			}
		}
	}
	
	public void setProblemCollectingActive(boolean collect) {
		ICompilationUnit cu = getCompilationUnit();
		if (cu != null) {
			getProblemRequestor().setIsActive(collect);
		}
	}
	
	public void classpathChange() {
		
		if(fDocumentScope!=null){
			fDocumentScope.classpathChange();
		}
	}
}