/*=============================================================================#
 # Copyright (c) 2007, 2021 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.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.internal.ltk.core.LtkCorePlugin;
import org.eclipse.statet.ltk.core.SourceContent;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;


/**
 * BasicWorkingBuffer using {@link ITextFileBuffer} and following JFace UI rules.
 * <p>
 * Usually used for editors / the editor context.</p>
 */
@NonNullByDefault
public class FileBufferWorkingBuffer extends BasicWorkingBuffer {
	
	
	private @Nullable ITextFileBuffer fileBuffer;
	
	
	public FileBufferWorkingBuffer(final SourceUnit unit) {
		super(unit);
	}
	
	
	@Override
	protected final byte getContentMode() {
		return DOCUMENT;
	}
	
	@Override
	protected @Nullable AbstractDocument createDocument(final SubMonitor m) {
		ITextFileBuffer fileBuffer= null;
		switch (detectResourceMode()) {
		case IFILE:
			{	final IPath path= ((IFile)this.unit.getResource()).getFullPath();
				try {
					FileBuffers.getTextFileBufferManager().connect(path, LocationKind.IFILE, m);
					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);
					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);
		}
		
		this.fileBuffer= fileBuffer;
		if (fileBuffer != null) {
			final IDocument fileDoc= fileBuffer.getDocument();
			if (fileDoc instanceof AbstractDocument) {
				return (AbstractDocument)fileDoc;
			}
		}
		return null;
	}
	
	private @Nullable ITextFileBuffer getBuffer() {
		synchronized (this) {
			final ITextFileBuffer fileBuffer= this.fileBuffer;
			if (fileBuffer != null) {
				return 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;
	}
	
}
