/*******************************************************************************
 * Copyright (c) 2007, 2011 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
 *     Andrew Ferguson (Symbian) - [api] enable document setup participants to customize behaviour based on resource being opened - https://bugs.eclipse.org/bugs/show_bug.cgi?id=208881
 *******************************************************************************/
package org.eclipse.core.internal.filebuffers;

import java.util.ArrayList;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.IAnnotationModelFactory;
import org.eclipse.core.filebuffers.IDocumentSetupParticipant;
import org.eclipse.core.filebuffers.IDocumentSetupParticipantExtension;
import org.eclipse.core.filebuffers.IFileBuffer;
import org.eclipse.core.filebuffers.IStateValidationSupport;
import org.eclipse.core.filebuffers.LocationKind;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension4;
import org.eclipse.jface.text.source.IAnnotationModel;


/**
 * @since 3.3
 */
public class ResourceTextFileBufferManager extends TextFileBufferManager {



	public ResourceTextFileBufferManager() {
		fRegistry= new ResourceExtensionRegistry();
	}

	@Override
	public boolean isTextFileLocation(IPath location, boolean strict) {
		Assert.isNotNull(location);
		location= FileBuffers.normalizeLocation(location);

		IFile file= FileBuffers.getWorkspaceFileAtLocation(location, true);
		if (file != null) {
			if (file.exists()) {
				try {
					IContentDescription description= file.getContentDescription();
					if (description != null) {
						IContentType type= description.getContentType();
						if (type != null)
							return type.isKindOf(TEXT_CONTENT_TYPE);
					}
				} catch (CoreException x) {
					// ignore: API specification tells return true if content type can't be determined
				}
			} else {
				IContentTypeManager manager= Platform.getContentTypeManager();
				IContentType[] contentTypes= manager.findContentTypesFor(file.getName());
				if (contentTypes != null && contentTypes.length > 0) {
					for (IContentType contentType : contentTypes)
						if (contentType.isKindOf(TEXT_CONTENT_TYPE))
							return true;
					return false;
				}
			}
			return !strict;
		}

		return isTextFileLocation(FileBuffers.getFileStoreAtLocation(location), strict);
	}

	@Override
	public String getDefaultEncoding() {
		return ResourcesPlugin.getEncoding();
	}

	@Override
	protected IPath normalizeLocation(IPath location) {
		return FileBuffers.normalizeLocation(location);
	}

	@Override
	protected AbstractFileBuffer createTextFileBuffer(IPath location, LocationKind locationKind) {
		if (locationKind == LocationKind.IFILE || locationKind == LocationKind.NORMALIZE  && FileBuffers.getWorkspaceFileAtLocation(location, true) != null)
			return new ResourceTextFileBuffer(this);
		return new FileStoreTextFileBuffer(this);
	}

	IAnnotationModel createAnnotationModel(IFile file) {
		Assert.isNotNull(file);
		IAnnotationModelFactory factory= ((ResourceExtensionRegistry)fRegistry).getAnnotationModelFactory(file);
		if (factory != null)
			return factory.createAnnotationModel(file.getFullPath());
		return null;
	}

	public IDocument createEmptyDocument(final IFile file) {
		IDocument documentFromFactory= createEmptyDocumentFromFactory(file);
		final IDocument document;
		if (documentFromFactory != null)
			document= documentFromFactory;
		else
			document= new SynchronizableDocument();

		// Set the initial line delimiter
		if (document instanceof IDocumentExtension4) {
			String initalLineDelimiter= getLineDelimiterPreference(file);
			if (initalLineDelimiter != null)
				((IDocumentExtension4)document).setInitialLineDelimiter(initalLineDelimiter);
		}

		final IDocumentSetupParticipant[] participants= ((ResourceExtensionRegistry)fRegistry).getDocumentSetupParticipants(file);
		if (participants != null) {
			for (final IDocumentSetupParticipant participant : participants) {
				ISafeRunnable runnable= new ISafeRunnable() {
					@Override
					public void run() throws Exception {
						if (participant instanceof IDocumentSetupParticipantExtension)
							((IDocumentSetupParticipantExtension)participant).setup(document, file.getFullPath(), LocationKind.IFILE);
						else
							participant.setup(document);

						if (document.getDocumentPartitioner() != null) {
							String message= NLSUtility.format(FileBuffersMessages.TextFileBufferManager_warning_documentSetupInstallsDefaultPartitioner, participant.getClass());
							IStatus status= new Status(IStatus.WARNING, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, message, null);
							FileBuffersPlugin.getDefault().getLog().log(status);
						}
					}
					@Override
					public void handleException(Throwable t) {
						IStatus status= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, FileBuffersMessages.TextFileBufferManager_error_documentSetupFailed, t);
						FileBuffersPlugin.getDefault().getLog().log(status);
					}
				};
				SafeRunner.run(runnable);
			}
		}

		return document;
	}

	/**
	 * Helper to get rid of deprecation warnings.
	 *
	 * @param file the file
	 * @return the created empty document or <code>null</code> if none got created
	 * @since 3.5
	 * @deprecated As of 3.5
	 */
	@Deprecated
	private IDocument createEmptyDocumentFromFactory(final IFile file) {
		final IDocument[] runnableResult= new IDocument[1];
		final org.eclipse.core.filebuffers.IDocumentFactory factory= ((ResourceExtensionRegistry)fRegistry).getDocumentFactory(file);
		if (factory != null) {
			ISafeRunnable runnable= new ISafeRunnable() {
				@Override
				public void run() throws Exception {
					runnableResult[0]= factory.createDocument();
				}
				@Override
				public void handleException(Throwable t) {
					IStatus status= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, FileBuffersMessages.TextFileBufferManager_error_documentFactoryFailed, t);
					FileBuffersPlugin.getDefault().getLog().log(status);
				}
			};
			SafeRunner.run(runnable);
		}
		return runnableResult[0];
	}

	private String getLineDelimiterPreference(IFile file) {
		IScopeContext[] scopeContext;
		if (file != null && file.getProject() != null) {
			// project preference
			scopeContext= new IScopeContext[] { new ProjectScope(file.getProject()) };
			String lineDelimiter= Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null, scopeContext);
			if (lineDelimiter != null)
				return lineDelimiter;
		}
		// workspace preference
		scopeContext= new IScopeContext[] { InstanceScope.INSTANCE };
		return Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null, scopeContext);
	}

	@Override
	protected String getLineDelimiterPreference(IPath location, LocationKind locationKind) {
		IFile file= null;
		if (locationKind != LocationKind.LOCATION)
			file= FileBuffers.getWorkspaceFileAtLocation(location);
		return getLineDelimiterPreference(file);
	}

	@Override
	public void validateState(final IFileBuffer[] fileBuffers, IProgressMonitor monitor, final Object computationContext) throws CoreException {
		IWorkspaceRunnable runnable= new IWorkspaceRunnable() {
			@Override
			public void run(IProgressMonitor progressMonitor) throws CoreException {
				IFileBuffer[] toValidate= findFileBuffersToValidate(fileBuffers);
				validationStateAboutToBeChanged(toValidate);
				try {
					IStatus status= validateEdit(toValidate, computationContext);
					validationStateChanged(toValidate, true, status);
				} catch (RuntimeException x) {
					validationStateChangedFailed(toValidate);
				}
			}
		};
		ResourcesPlugin.getWorkspace().run(runnable, computeValidateStateRule(fileBuffers), IWorkspace.AVOID_UPDATE, monitor);
	}

	private IStatus validateEdit(IFileBuffer[] fileBuffers, Object computationContext) {
		ArrayList<IFile> list= new ArrayList<>();
		for (IFileBuffer fileBuffer : fileBuffers) {
			IFile file= getWorkspaceFile(fileBuffer);
			if (file != null)
				list.add(file);
		}
		IFile[] files= new IFile[list.size()];
		list.toArray(files);
		return ResourcesPlugin.getWorkspace().validateEdit(files, computationContext);
	}

	private IFileBuffer[] findFileBuffersToValidate(IFileBuffer[] fileBuffers) {
		ArrayList<IFileBuffer> list= new ArrayList<>();
		for (int i= 0; i < fileBuffers.length; i++) {
			if (!fileBuffers[i].isStateValidated())
				list.add(fileBuffers[i]);
		}
		return list.toArray(new IFileBuffer[list.size()]);
	}

	private void validationStateAboutToBeChanged(IFileBuffer[] fileBuffers) {
		for (IFileBuffer fileBuffer : fileBuffers) {
			if (fileBuffer instanceof IStateValidationSupport) {
				IStateValidationSupport support= (IStateValidationSupport) fileBuffer;
				support.validationStateAboutToBeChanged();
			}
		}
	}

	private void validationStateChanged(IFileBuffer[] fileBuffers, boolean validationState, IStatus status) {
		for (IFileBuffer fileBuffer : fileBuffers) {
			if (fileBuffer instanceof IStateValidationSupport) {
				IStateValidationSupport support= (IStateValidationSupport) fileBuffer;
				support.validationStateChanged(validationState, status);
			}
		}
	}

	private void validationStateChangedFailed(IFileBuffer[] fileBuffers) {
		for (IFileBuffer fileBuffer : fileBuffers) {
			if (fileBuffer instanceof IStateValidationSupport) {
				IStateValidationSupport support= (IStateValidationSupport) fileBuffer;
				support.validationStateChangeFailed();
			}
		}
	}

	private IFile getWorkspaceFile(IFileBuffer fileBuffer) {
		return FileBuffers.getWorkspaceFileAtLocation(fileBuffer.getLocation());
	}

	private ISchedulingRule computeValidateStateRule(IFileBuffer[] fileBuffers) {
		ArrayList<IResource> list= new ArrayList<>();
		for (IFileBuffer fileBuffer : fileBuffers) {
			IResource resource= getWorkspaceFile(fileBuffer);
			if (resource != null)
				list.add(resource);
		}
		IResource[] resources= new IResource[list.size()];
		list.toArray(resources);
		IResourceRuleFactory factory= ResourcesPlugin.getWorkspace().getRuleFactory();
		return factory.validateEditRule(resources);
	}

}
