/*******************************************************************************
 * Copyright (c) 2007, 2014 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     James Blackburn <jamesblackburn+eclipse@gmail.com> - [implementation] FileStoreTextFileBuffer eats IOException on external file save - https://bugs.eclipse.org/333660
 *******************************************************************************/
package org.eclipse.core.internal.filebuffers;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.SequenceInputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnmappableCharacterException;
import java.nio.charset.UnsupportedCharsetException;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;

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.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;

import org.eclipse.core.resources.IResourceStatus;

import org.eclipse.core.filebuffers.IFileBufferStatusCodes;
import org.eclipse.core.filebuffers.IPersistableAnnotationModel;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.LocationKind;

import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.source.IAnnotationModel;

/**
 * @since 3.3 (previously available as JavaTextFileBuffer since 3.3)
 */
public class FileStoreTextFileBuffer extends FileStoreFileBuffer implements ITextFileBuffer {


	private class DocumentListener implements IDocumentListener {

		@Override
		public void documentAboutToBeChanged(DocumentEvent event) {
			// do nothing
		}

		@Override
		public void documentChanged(DocumentEvent event) {
			fCanBeSaved= true;
			removeFileBufferContentListeners();
			fManager.fireDirtyStateChanged(FileStoreTextFileBuffer.this, fCanBeSaved);
		}
	}

	/**
	 * Reader chunk size.
	 */
	private static final int READER_CHUNK_SIZE= 2048;
	/**
	 * Buffer size.
	 */
	private static final int BUFFER_SIZE= 8 * READER_CHUNK_SIZE;
	/**
	 * Constant for representing the error status. This is considered a value object.
	 */
	private static final IStatus STATUS_ERROR= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, FileBuffersMessages.FileBuffer_status_error, null);

	/**
	 * Constant denoting an empty set of properties
	 * @since 3.1
	 */
	private static final QualifiedName[] NO_PROPERTIES= new QualifiedName[0];


	/** The element's document */
	protected IDocument fDocument;
	/** The encoding used to create the document from the storage or <code>null</code> for workbench encoding. */
	protected String fEncoding;
	/** Internal document listener */
	protected IDocumentListener fDocumentListener= new DocumentListener();
	/** The encoding which has explicitly been set on the file. */
	private String fExplicitEncoding;
	/** Tells whether the file on disk has a BOM. */
	private boolean fHasBOM;
	/** The annotation model of this file buffer */
	private IAnnotationModel fAnnotationModel;
	/**
	 * Lock for lazy creation of annotation model.
	 * @since 3.2
	 */
	private final Object fAnnotationModelCreationLock= new Object();
	/**
	 * Tells whether the cache is up to date.
	 * @since 3.2
	 */
	private boolean fIsCacheUpdated= false;


	public FileStoreTextFileBuffer(TextFileBufferManager manager) {
		super(manager);
	}

	@Override
	public IDocument getDocument() {
		return fDocument;
	}

	@Override
	public IAnnotationModel getAnnotationModel() {
		synchronized (fAnnotationModelCreationLock) {
			if (fAnnotationModel == null && !isDisconnected()) {
				fAnnotationModel= fManager.createAnnotationModel(getLocationOrName(), LocationKind.LOCATION);
				if (fAnnotationModel != null)
					fAnnotationModel.connect(fDocument);
			}
		}
		return fAnnotationModel;
	}

	@Override
	public String getEncoding() {
		if (!fIsCacheUpdated)
			cacheEncodingState();
		return fEncoding;
	}

	@Override
	public void setEncoding(String encoding) {
		fExplicitEncoding= encoding;
		if (encoding == null || encoding.equals(fEncoding))
			fIsCacheUpdated= false;
		else {
			fEncoding= encoding;
			fHasBOM= false;
		}
	}

	@Override
	public IStatus getStatus() {
		if (!isDisconnected()) {
			if (fStatus != null)
				return fStatus;
			return (fDocument == null ? STATUS_ERROR : Status.OK_STATUS);
		}
		return STATUS_ERROR;
	}

	private InputStream getFileContents(IFileStore fileStore) throws CoreException {
		if (!fFileStore.fetchInfo().exists())
			return null;

		return fileStore.openInputStream(EFS.NONE, null);
	}

	private void setFileContents(InputStream stream, IProgressMonitor monitor) throws CoreException {
		try(OutputStream out= fFileStore.openOutputStream(EFS.NONE, null)) {
			byte[] buffer= new byte[8192];
			while (true) {
				int bytesRead= -1;
				bytesRead= stream.read(buffer);
				if (bytesRead == -1) {
					out.close();
					break;
				}
				out.write(buffer, 0, bytesRead);
				if (monitor != null)
					monitor.worked(1);
			}
		} catch (IOException ex) {
			String message= (ex.getMessage() != null ? ex.getMessage() : ""); //$NON-NLS-1$
			IStatus s= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, message, ex);
			throw new CoreException(s);
		} finally {
			try {
				stream.close();
			} catch (IOException e) {
				// ignore
			}
		}
	}

	@Override
	public void revert(IProgressMonitor monitor) throws CoreException {
		if (isDisconnected())
			return;

		IDocument original= null;
		fStatus= null;

		try {
			original= fManager.createEmptyDocument(getLocationOrName(), LocationKind.LOCATION);
			cacheEncodingState();
			setDocumentContent(original, fFileStore, fEncoding, fHasBOM, monitor);
		} catch (CoreException x) {
			fStatus= x.getStatus();
		}

		if (original == null)
			return;

		String originalContents= original.get();
		boolean replaceContents= !originalContents.equals(fDocument.get());

		if (!replaceContents && !fCanBeSaved)
			return;

		fManager.fireStateChanging(this);
		try {

			if (replaceContents)  {
				fManager.fireBufferContentAboutToBeReplaced(this);
				fDocument.set(original.get());
			}

			boolean fireDirtyStateChanged= fCanBeSaved;
			if (fCanBeSaved) {
				fCanBeSaved= false;
				addFileBufferContentListeners();
			}

			if (replaceContents)
				fManager.fireBufferContentReplaced(this);

			IFileInfo info= fFileStore.fetchInfo();
			if (info.exists())
				fSynchronizationStamp= fFileStore.fetchInfo().getLastModified();

			if (fAnnotationModel instanceof IPersistableAnnotationModel) {
				IPersistableAnnotationModel persistableModel= (IPersistableAnnotationModel) fAnnotationModel;
				try {
					persistableModel.revert(fDocument);
				} catch (CoreException x) {
					fStatus= x.getStatus();
				}
			}

			if (fireDirtyStateChanged)
				fManager.fireDirtyStateChanged(this, fCanBeSaved);

		} catch (RuntimeException x) {
			fManager.fireStateChangeFailed(this);
			throw x;
		}
	}

	/*
	 * @see org.eclipse.core.filebuffers.IFileBuffer#getContentType()
	 * @since 3.1
	 */
	@Override
	public IContentType getContentType () throws CoreException {
		try {
			if (isDirty()) {
				try(Reader reader= new DocumentReader(getDocument())) {
					IContentDescription desc= Platform.getContentTypeManager().getDescriptionFor(reader, fFileStore.getName(), NO_PROPERTIES);
					if (desc != null && desc.getContentType() != null)
						return desc.getContentType();
				}
			}

			try(InputStream stream= fFileStore.openInputStream(EFS.NONE, null)) {
				IContentDescription desc= Platform.getContentTypeManager().getDescriptionFor(stream, fFileStore.getName(), NO_PROPERTIES);
				if (desc != null && desc.getContentType() != null)
					return desc.getContentType();
				return null;
			}
		} catch (IOException x) {
			throw new CoreException(new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, NLSUtility.format(FileBuffersMessages.FileBuffer_error_queryContentDescription, fFileStore.toString()), x));
		}
	}

	@Override
	protected void addFileBufferContentListeners() {
		if (fDocument != null)
			fDocument.addDocumentListener(fDocumentListener);
	}

	@Override
	protected void removeFileBufferContentListeners() {
		if (fDocument != null)
			fDocument.removeDocumentListener(fDocumentListener);
	}

	@Override
	protected void initializeFileBufferContent(IProgressMonitor monitor) throws CoreException {
		try {
			fDocument= fManager.createEmptyDocument(getLocationOrName(), LocationKind.LOCATION);
			cacheEncodingState();
			setDocumentContent(fDocument, fFileStore, fEncoding, fHasBOM, monitor);
		} catch (CoreException x) {
			fDocument= fManager.createEmptyDocument(getLocationOrName(), LocationKind.LOCATION);
			fStatus= x.getStatus();
		}
	}

	@Override
	protected void connected() {
		super.connected();
		if (fAnnotationModel != null)
			fAnnotationModel.connect(fDocument);
	}

	@Override
	protected void disconnected() {
		if (fAnnotationModel != null)
			fAnnotationModel.disconnect(fDocument);
		super.disconnected();
	}

	protected void cacheEncodingState() {
		fEncoding= fExplicitEncoding;
		fHasBOM= false;
		fIsCacheUpdated= true;

		try(InputStream stream= getFileContents(fFileStore)) {
			if (stream == null)
				return;

			QualifiedName[] options= new QualifiedName[] { IContentDescription.CHARSET, IContentDescription.BYTE_ORDER_MARK };
			IContentDescription description= Platform.getContentTypeManager().getDescriptionFor(stream, fFileStore.getName(), options);
			if (description != null) {
				fHasBOM= description.getProperty(IContentDescription.BYTE_ORDER_MARK) != null;
				if (fEncoding == null)
					fEncoding= description.getCharset();
			}
		} catch (CoreException e) {
			// do nothing
		} catch (IOException e) {
			// do nothing
		}

		// Use global default
		if (fEncoding == null)
			fEncoding= fManager.getDefaultEncoding();

	}

	@Override
	protected void commitFileBufferContent(IProgressMonitor monitor, boolean overwrite) throws CoreException {
		if (!isSynchronized() && !overwrite) {
			String message= NLSUtility.format(FileBuffersMessages.FileBuffer_error_outOfSync, getFileStore().toURI());
			throw new CoreException(new Status(IStatus.WARNING, FileBuffersPlugin.PLUGIN_ID, IResourceStatus.OUT_OF_SYNC_LOCAL, message, null));
		}

		String encoding= computeEncoding();

		Charset charset;
		try {
			charset= Charset.forName(encoding);
		} catch (UnsupportedCharsetException ex) {
			String message= NLSUtility.format(FileBuffersMessages.ResourceTextFileBuffer_error_unsupported_encoding_message_arg, encoding);
			IStatus s= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, message, ex);
			throw new CoreException(s);
		} catch (IllegalCharsetNameException ex) {
			String message= NLSUtility.format(FileBuffersMessages.ResourceTextFileBuffer_error_illegal_encoding_message_arg, encoding);
			IStatus s= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, message, ex);
			throw new CoreException(s);
		}

		CharsetEncoder encoder= charset.newEncoder();
		encoder.onMalformedInput(CodingErrorAction.REPLACE);
		encoder.onUnmappableCharacter(CodingErrorAction.REPORT);

		byte[] bytes;
		int bytesLength;

		try {
			ByteBuffer byteBuffer= encoder.encode(CharBuffer.wrap(fDocument.get()));
			bytesLength= byteBuffer.limit();
			if (byteBuffer.hasArray())
				bytes= byteBuffer.array();
			else {
				bytes= new byte[bytesLength];
				byteBuffer.get(bytes);
			}
		} catch (CharacterCodingException ex) {
			Assert.isTrue(ex instanceof UnmappableCharacterException);
			String message= NLSUtility.format(FileBuffersMessages.ResourceTextFileBuffer_error_charset_mapping_failed_message_arg, encoding);
			IStatus s= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IFileBufferStatusCodes.CHARSET_MAPPING_FAILED, message, null);
			throw new CoreException(s);
		}

		IFileInfo fileInfo= fFileStore.fetchInfo();
		if (fileInfo != null && fileInfo.exists()) {

			if (!overwrite)
				checkSynchronizationState();

			InputStream stream= new ByteArrayInputStream(bytes, 0, bytesLength);

			/*
			 * XXX:
			 * This is a workaround for a corresponding bug in Java readers and writer,
			 * see http://developer.java.sun.com/developer/bugParade/bugs/4508058.html
			 */
			if (fHasBOM && StandardCharsets.UTF_8.name().equals(encoding))
				stream= new SequenceInputStream(new ByteArrayInputStream(IContentDescription.BOM_UTF_8), stream);


			// here the file synchronizer should actually be removed and afterwards added again. However,
			// we are already inside an operation, so the delta is sent AFTER we have added the listener
			setFileContents(stream, monitor);
			// set synchronization stamp to know whether the file synchronizer must become active
			fSynchronizationStamp= fFileStore.fetchInfo().getLastModified();

			if (fAnnotationModel instanceof IPersistableAnnotationModel) {
				IPersistableAnnotationModel persistableModel= (IPersistableAnnotationModel) fAnnotationModel;
				persistableModel.commit(fDocument);
			}

		} else {
			fFileStore.getParent().mkdir(EFS.NONE, null);

			try(OutputStream out= fFileStore.openOutputStream(EFS.NONE, null)) {
				/*
				 * XXX:
				 * This is a workaround for a corresponding bug in Java readers and writer,
				 * see http://developer.java.sun.com/developer/bugParade/bugs/4508058.html
				 */
				if (fHasBOM && StandardCharsets.UTF_8.name().equals(encoding))
					out.write(IContentDescription.BOM_UTF_8);

				out.write(bytes, 0, bytesLength);
				out.flush();
				out.close();
			} catch (IOException x) {
				IStatus s= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, x.getLocalizedMessage(), x);
				throw new CoreException(s);
			}

			// set synchronization stamp to know whether the file synchronizer must become active
			fSynchronizationStamp= fFileStore.fetchInfo().getLastModified();

		}
	}

	private String computeEncoding() {
		// Make sure cache is up to date
		if (!fIsCacheUpdated)
			cacheEncodingState();

		// User-defined encoding has first priority
		if (fExplicitEncoding != null)
			return fExplicitEncoding;

		// Probe content
		try(Reader reader= new DocumentReader(fDocument)) {
			QualifiedName[] options= new QualifiedName[] { IContentDescription.CHARSET, IContentDescription.BYTE_ORDER_MARK };
			IContentDescription description= Platform.getContentTypeManager().getDescriptionFor(reader, fFileStore.getName(), options);
			if (description != null) {
				String encoding= description.getCharset();
				if (encoding != null)
					return encoding;
			}
		} catch (IOException ex) {
			// Try next strategy
		}

		// Use file's encoding if the file has a BOM
		if (fHasBOM)
			return fEncoding;

		// Use global default
		return fManager.getDefaultEncoding();
	}

	/**
	 * Initializes the given document with the given file's content using the given encoding.
	 *
	 * @param document the document to be initialized
	 * @param file the file which delivers the document content
	 * @param encoding the character encoding for reading the given stream
	 * @param hasBOM tell whether the given file has a BOM
	 * @param monitor the progress monitor
	 * @exception CoreException if the given stream can not be read
	 */
	private void setDocumentContent(IDocument document, IFileStore file, String encoding, boolean hasBOM, IProgressMonitor monitor) throws CoreException {
		InputStream contentStream= getFileContents(file);
		if (contentStream == null)
			return;

		Reader in= null;
		try {

			if (encoding == null)
				encoding= fManager.getDefaultEncoding();

			/*
			 * XXX:
			 * This is a workaround for a corresponding bug in Java readers and writer,
			 * see http://developer.java.sun.com/developer/bugParade/bugs/4508058.html
			 */
			if (hasBOM && StandardCharsets.UTF_8.name().equals(encoding)) {
				int n= 0;
				do {
					int bytes= contentStream.read(new byte[IContentDescription.BOM_UTF_8.length]);
					if (bytes == -1)
						throw new IOException();
					n += bytes;
				} while (n < IContentDescription.BOM_UTF_8.length);
			}

			in= new BufferedReader(new InputStreamReader(contentStream, encoding), BUFFER_SIZE);
			StringBuilder buffer= new StringBuilder(BUFFER_SIZE);
			char[] readBuffer= new char[READER_CHUNK_SIZE];
			int n= in.read(readBuffer);
			while (n > 0) {
				buffer.append(readBuffer, 0, n);
				n= in.read(readBuffer);
			}

			document.set(buffer.toString());

		} catch (IOException x) {
			String msg= x.getMessage() == null ? "" : x.getMessage(); //$NON-NLS-1$
			IStatus s= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, IStatus.OK, msg, x);
			throw new CoreException(s);
		} finally {
			try {
				if (in != null)
					in.close();
				else
					contentStream.close();
			} catch (IOException x) {
			}
		}
	}

	/**
	 * Checks whether the given file is synchronized with the local file system.
	 * If the file has been changed, a <code>CoreException</code> is thrown.
	 *
	 * @exception CoreException if file has been changed on the file system
	 */
	private void checkSynchronizationState() throws CoreException {
		if (!isSynchronized()) {
			String message= NLSUtility.format(FileBuffersMessages.FileBuffer_error_outOfSync, getFileStore().toURI());
			Status status= new Status(IStatus.ERROR, FileBuffersPlugin.PLUGIN_ID, 274 /* IResourceStatus.OUT_OF_SYNC_LOCAL */, message, null);
			throw new CoreException(status);
		}
	}

	/**
	 * Returns the location if it is <code>null</code> or
	 * the name as <code>IPath</code> otherwise.
	 *
	 * @return a non-null <code>IPath</code>
	 * @since 3.3.1
	 */
	private IPath getLocationOrName() {
		IPath path= getLocation();
		if (path == null)
			path= new Path(fFileStore.getName());
		return path;
	}
}
