/*=============================================================================#
 # Copyright (c) 2007, 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.model.core.impl;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.IDocument;

import org.eclipse.statet.internal.ltk.core.LTKCorePlugin;
import org.eclipse.statet.ltk.core.SourceContent;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;


/**
 * WorkingBuffer using {@link ITextFileBuffer} and following JFace UI rules.
 * <p>
 * Usually used for editors / the editor context.</p>
 */
public class FileBufferWorkingBuffer extends WorkingBuffer {
	
	
	private ITextFileBuffer fileBuffer;
	
	
	public FileBufferWorkingBuffer(final ISourceUnit unit) {
		super(unit);
	}
	
	
	@Override
	protected final byte getContentMode() {
		return DOCUMENT;
	}
	
	@Override
	protected AbstractDocument createDocument(final SubMonitor m) {
		switch (detectResourceMode()) {
		case IFILE:
			{	final IPath path= ((IFile) this.unit.getResource()).getFullPath();
				try {
					FileBuffers.getTextFileBufferManager().connect(path, LocationKind.IFILE, m);
					this.fileBuffer= FileBuffers.getTextFileBufferManager().getTextFileBuffer(path, LocationKind.IFILE);
				}
				catch (final CoreException e) {
					LTKCorePlugin.log(new Status(IStatus.ERROR, LTKCorePlugin.BUNDLE_ID, -1,
							"An error occurred when allocating the document of the file buffer.",
							e ));
				}
				break;
			}
		case FILESTORE:
			{	final IFileStore store= (IFileStore) this.unit.getResource();
				try {
					FileBuffers.getTextFileBufferManager().connectFileStore(store, m);
					this.fileBuffer= FileBuffers.getTextFileBufferManager().getFileStoreTextFileBuffer(store);
				}
				catch (final CoreException e) {
					LTKCorePlugin.log(new Status(IStatus.ERROR, LTKCorePlugin.BUNDLE_ID, -1,
							"An error occurred when allocating the document of the file buffer.",
							e ));
				}
				break;
			}
		default:
			return super.createDocument(m);
		}
		
		if (this.fileBuffer != null) {
			final IDocument fileDoc= this.fileBuffer.getDocument();
			if (fileDoc instanceof AbstractDocument) {
				return (AbstractDocument) fileDoc;
			}
		}
		return null;
	}
	
	private ITextFileBuffer getBuffer() {
		synchronized (this) {
			if (this.fileBuffer != null) {
				return this.fileBuffer;
			}
		}
		switch (getResourceMode()) {
		case IFILE:
			{	final IPath path= ((IFile) this.unit.getResource()).getFullPath();
				return FileBuffers.getTextFileBufferManager().getTextFileBuffer(path, LocationKind.IFILE);
			}
		case FILESTORE:
			{	final IFileStore store= (IFileStore) this.unit.getResource();
				return FileBuffers.getTextFileBufferManager().getFileStoreTextFileBuffer(store);
			}
		default:
			return null;
		}
	}
	
	@Override
	protected SourceContent createContent(final SubMonitor m) {
		if (detectResourceMode() > 0) {
			final ITextFileBuffer buffer= getBuffer();
			if (buffer != null) {
				return createContentFromDocument(buffer.getDocument());
			}
		}
		return super.createContent(m);
	}
	
	@Override
	public void releaseDocument(final IProgressMonitor monitor) {
		if (this.fileBuffer != null) {
			try {
				final SubMonitor m= SubMonitor.convert(monitor);
				switch (getResourceMode()) {
				case IFILE:
					{	final IPath path= ((IFile) this.unit.getResource()).getFullPath();
						FileBuffers.getTextFileBufferManager().disconnect(path, LocationKind.IFILE, m);
						break;
					}
				case FILESTORE:
					{	final IFileStore store= (IFileStore) this.unit.getResource();
						FileBuffers.getTextFileBufferManager().disconnectFileStore(store, m);
						break;
					}
				default:
					break;
				}
			}
			catch (final CoreException e) {
				LTKCorePlugin.log(new Status(IStatus.ERROR, LTKCorePlugin.BUNDLE_ID, -1,
						"An error occurred when releasing the document of the file buffer.", e ));
			}
			finally {
				this.fileBuffer= null;
				super.releaseDocument(monitor);
			}
		}
		else {
			super.releaseDocument(monitor);
		}
	}
	
	@Override
	public boolean checkState(final boolean validate, final IProgressMonitor monitor) {
		final ITextFileBuffer buffer= this.fileBuffer;
		if (buffer != null) {
			if (!validate && !buffer.isStateValidated()) {
				return true;
			}
			if (validate && !buffer.isStateValidated()) {
				try {
					buffer.validateState(monitor, IWorkspace.VALIDATE_PROMPT);
				}
				catch (final CoreException e) {
					LTKCorePlugin.log(new Status(IStatus.ERROR, LTKCorePlugin.BUNDLE_ID, -1,
							"An error occurred when validating file buffer state.", e ));
				}
			}
		}
		return super.checkState(validate, monitor);
	}
	
	@Override
	public boolean isSynchronized() {
		if (detectResourceMode() > 0) {
			final ITextFileBuffer buffer= getBuffer();
			if (buffer != null) {
				return !buffer.isDirty();
			}
		}
		return true;
	}
	
}
