/*=============================================================================#
 # 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 java.io.BufferedReader;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
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.jface.text.IDocumentExtension4;
import org.eclipse.jface.text.ISynchronizable;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.ecommons.io.FileUtil;

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


/**
 * Common implementation of {@link WorkingBuffer} for source units based on
 * an {@link IFile} or an {@link IFileStore}.
 */
@NonNullByDefault
public class BasicWorkingBuffer implements WorkingBuffer {
	
	/** Mode for IFile (in workspace) */
	protected static final byte IFILE= 1;
	/** Mode for IFileStore (URI) */
	protected static final byte FILESTORE= 2;
	
	protected static final byte DOCUMENT= 1;
	
	
	public static SourceContent createContentFromDocument(final IDocument doc) {
		Object lock= null;
		if (doc instanceof ISynchronizable) {
			lock= ((ISynchronizable)doc).getLockObject();
		}
		if (lock != null && doc instanceof IDocumentExtension4) {
			synchronized (lock) {
				return new SourceContent(
						((IDocumentExtension4)doc).getModificationStamp(),
						doc.get() );
			}
		}
		else {
			return new SourceContent(System.currentTimeMillis(), doc.get());
		}
	}
	
	
	protected final SourceUnit unit;
	private @Nullable AbstractDocument document;
	
	/**
	 * Mode of this working buffer:<ul>
	 *   <li>= 0 - uninitialized</li>
	 *   <li>< 0 - invalid/no source found</li>
	 *   <li>> 0 - mode constant {@link #IFILE}, {@link #FILESTORE}</li>
	 * </ul>
	 */
	private byte mode;
	
	public BasicWorkingBuffer(final SourceUnit unit) {
		this.unit= unit;
	}
	
	
	/**
	 * Checks the mode of this working buffer
	 * 
	 * @return <code>true</code> if valid mode, otherwise <code>false</code>
	 */
	protected final byte detectResourceMode() {
		if (this.mode == 0) {
			final Object resource= this.unit.getResource();
			if (resource instanceof IFile) {
				this.mode= IFILE;
			}
			else if (resource instanceof IFileStore 
					&& !((IFileStore)resource).fetchInfo().isDirectory() ) {
				this.mode= FILESTORE;
			}
			if (this.mode == 0) {
				this.mode= -1;
			}
		}
		return this.mode;
	}
	
	protected final byte getResourceMode() {
		return this.mode;
	}
	
	protected byte getContentMode() {
		return 0;
	}
	
	
	@Override
	public long getContentStamp(final IProgressMonitor monitor) {
		{	final AbstractDocument doc= this.document;
			if (doc != null) {
				return doc.getModificationStamp();
			}
		}
		{	final SourceUnit underlyingUnit= this.unit.getUnderlyingUnit();
			if (underlyingUnit != null) {
				return underlyingUnit.getContentStamp(monitor);
			}
		}
		if (detectResourceMode() == IFILE) {
			final IFile resource= (IFile)this.unit.getResource();
			if (resource != null) {
				return resource.getModificationStamp();
			}
		}
		return 0;
	}
	
	@Override
	public synchronized @Nullable AbstractDocument getDocument() {
		return this.document;
	}
	
	@Override
	public synchronized AbstractDocument getDocument(final @Nullable IProgressMonitor monitor) {
		AbstractDocument doc= this.document;
		if (doc == null) {
			final SubMonitor m= SubMonitor.convert(monitor);
			doc= createDocument(m);
			checkDocument(doc);
			if ((getContentMode() & DOCUMENT) != 0) {
				this.document= doc;
			}
		}
		return doc;
	}
	
	@Override
	public SourceContent getContent(final IProgressMonitor monitor) {
		final SubMonitor m= SubMonitor.convert(monitor);
		final IDocument doc= ((getContentMode() & DOCUMENT) != 0) ? getDocument(monitor) : getDocument();
		if (doc != null) {
			return createContentFromDocument(doc);
		}
		return createContent(m);
	}
	
	@Override
	public void saveDocument(final IProgressMonitor monitor) {
	}
	
	@Override
	public synchronized void releaseDocument(final IProgressMonitor monitor) {
		this.document= null;
	}
	
	@Override
	public boolean checkState(final boolean validate, final IProgressMonitor monitor) {
		{	final SourceUnit underlyingUnit= this.unit.getUnderlyingUnit();
			if (underlyingUnit != null) {
				return underlyingUnit.checkState(validate, monitor);
			}
		}
		switch (detectResourceMode()) {
		case IFILE:
			{	final IFile resource= (IFile)this.unit.getResource();
				if (!validate) {
					return !resource.getResourceAttributes().isReadOnly();
				}
				else {
					return resource.getWorkspace().validateEdit(new IFile[] { resource }, IWorkspace.VALIDATE_PROMPT).isOK();
				}
			}
		case FILESTORE:
			{	final IFileStore store= (IFileStore)this.unit.getResource();
				try {
					return !store.fetchInfo(EFS.NONE, monitor).getAttribute(EFS.ATTRIBUTE_READ_ONLY);
				}
				catch (final CoreException e) {
					LtkCorePlugin.log(new Status(IStatus.ERROR, LtkCorePlugin.BUNDLE_ID, 0,
							"An error occurred when checking modifiable state of the file.", e));
					return false;
				}
			}
		default:
			return false;
		}
	}
	
	
	protected @Nullable AbstractDocument createDocument(final SubMonitor m) {
		final IDocument fileDoc= createEmptyDocument();
		if (!(fileDoc instanceof AbstractDocument)) {
			return null;
		}
		final AbstractDocument document= (AbstractDocument)fileDoc;
		
		final SourceUnit underlyingUnit= this.unit.getUnderlyingUnit();
		if (underlyingUnit != null) {
			final SourceContent underlyingContent= underlyingUnit.getContent(m);
//			if (document instanceof IDocumentExtension4) {
			document.set(underlyingContent.getText(), underlyingContent.getStamp());
//			}
//			else {
//				document.set(underlyingContent.text);
//			}
		}
		else {
			final Object resource= this.unit.getResource();
			if (resource instanceof IFile) {
				loadDocumentFromFile((IFile)resource, document, m);
			}
		}
		
		return document;
	}
	
	private IDocument createEmptyDocument() {
		switch (detectResourceMode()) {
		case IFILE:
			return FileBuffers.getTextFileBufferManager().createEmptyDocument(
					((IFile)this.unit.getResource()).getFullPath(),
					LocationKind.IFILE );
		case FILESTORE:
			return FileBuffers.getTextFileBufferManager().createEmptyDocument(
					URIUtil.toPath(((IFileStore)this.unit.getResource()).toURI()),
					LocationKind.LOCATION );
		default:
			return FileBuffers.getTextFileBufferManager().createEmptyDocument(null, null);
		}
	}
	
	protected void checkDocument(final AbstractDocument document) {
		if (document instanceof ISynchronizable) {
			synchronized (document) {
				if (((ISynchronizable)document).getLockObject() == null) {
					((ISynchronizable)document).setLockObject(new Object());
				}
			}
		}
	}
	
	protected final void loadDocumentFromFile(final IFile file, final AbstractDocument document, final SubMonitor m) {
		try {
			FileUtil.getFileUtil(file).createReadTextFileOp(new FileUtil.ReaderAction() {
				@Override
				public void run(final BufferedReader reader, final IProgressMonitor monitor) throws IOException {
					final StringBuilder buffer= new StringBuilder();
					final char[] readBuffer= new char[2048];
					int n;
					while ((n= reader.read(readBuffer)) > 0) {
						buffer.append(readBuffer, 0, n);
					}
//					if (document instanceof IDocumentExtension4) {
					document.set(buffer.toString(), file.getModificationStamp());
//					}
//					else {
//						document.set(buffer.toString());
//					}
				}
			}).doOperation(m);
		}
		catch (final OperationCanceledException e) {
		}
		catch (final CoreException e) {
			LtkCorePlugin.log(e.getStatus());
		}
	}
	
	protected SourceContent createContent(final SubMonitor m) {
		final SourceUnit underlyingUnit= this.unit.getUnderlyingUnit();
		if (underlyingUnit != null) {
			return underlyingUnit.getContent(m);
		}
		else {
			final Object resource= this.unit.getResource();
			final AtomicReference<SourceContent> content= new AtomicReference<>();
			if (resource instanceof IFile) {
				loadContentFromFile((IFile)resource, content, m);
			}
			return content.get();
		}
	}
	
	protected final void loadContentFromFile(final IFile file, final AtomicReference<SourceContent> content, final SubMonitor m) {
		try {
			FileUtil.getFileUtil(file).createReadTextFileOp(new FileUtil.ReaderAction() {
				@Override
				public void run(final BufferedReader reader, final IProgressMonitor monitor) throws IOException {
					final StringBuilder buffer= new StringBuilder();
					final char[] readBuffer= new char[2048];
					int n;
					while ((n= reader.read(readBuffer)) >= 0) {
						buffer.append(readBuffer, 0, n);
					}
					content.set(new SourceContent(file.getModificationStamp(), buffer.toString()));
				}
			}).doOperation(m);
		}
		catch (final OperationCanceledException e) {
		}
		catch (final CoreException e) {
			LtkCorePlugin.log(e.getStatus());
		}
	}
	
	@Override
	public boolean isSynchronized() {
		return false;
	}
	
}
