/*******************************************************************************
 * Copyright (c) 2011, 2012 Ericsson
 * 
 * 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
 * 
 * Description:
 * 
 * Contributors:
 *   Alvaro Sanchez-Leon - Initial API
 *******************************************************************************/
package org.eclipse.mylyn.reviews.r4e.core.rfs;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.eclipse.core.resources.IStorage;
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.Status;
import org.eclipse.egit.core.RepositoryUtil;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.util.FS;
import org.eclipse.mylyn.reviews.r4e.core.Activator;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion;
import org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry;
import org.eclipse.mylyn.reviews.r4e.core.rfs.spi.ReviewsFileStorageException;
import org.eclipse.mylyn.reviews.r4e.core.utils.IOUtils;
import org.eclipse.mylyn.reviews.r4e.core.utils.filePermission.FileSupportCommandFactory;
import org.eclipse.team.core.history.IFileRevision;
import org.eclipse.team.core.history.provider.FileRevision;

/**
 * @author Alvaro Sanchez-Leon
 */
public class ReviewsRFSProxy implements IRFSRegistry {
	// ------------------------------------------------------------------------
	// Constants
	// ------------------------------------------------------------------------

	private static final String DEFAULT_REPO_NAME = "ReviewsRepo.git";

	private ObjectInserter fInserter = null;

	protected Repository fRepository = null;

	protected final RepositoryUtil fRepositoryUtil;

	// ------------------------------------------------------------------------
	// Constructors
	// ------------------------------------------------------------------------
	/**
	 * @param aParentDir
	 * @throws IOException
	 */
	public ReviewsRFSProxy(File aReviewGroupDir, boolean create) throws ReviewsFileStorageException {
		File repoLoc = new File(aReviewGroupDir, DEFAULT_REPO_NAME);
		if (create) {
			fRepository = initializeRepo(repoLoc);
			// Set writing permissions to the shared location
			try {
				FileSupportCommandFactory.getInstance().grantWritePermission(aReviewGroupDir.getAbsolutePath());
			} catch (IOException e) {
				throw new ReviewsFileStorageException(e);
			}
		} else {
			// permissions must have been already set
			fRepository = openRepository(repoLoc);
		}
		fInserter = fRepository.newObjectInserter();
		fRepositoryUtil = org.eclipse.egit.core.Activator.getDefault().getRepositoryUtil();
	}

	// ------------------------------------------------------------------------
	// Methods
	// ------------------------------------------------------------------------

	/**
	 * Validate if the given directory is a valid repository
	 * 
	 * @param dir
	 * @return
	 */
	public static boolean isValidRepo(File dir) {
		File repoDir = new File(dir, DEFAULT_REPO_NAME);
		return FileKey.isGitRepository(repoDir, FS.DETECTED);
	}

	/**
	 * @param aReviewGroupDir
	 * @return
	 * @throws ReviewsFileStorageException
	 */
	private Repository initializeRepo(File aReviewGroupDir) throws ReviewsFileStorageException {
		try {
			Repository newRepo = new FileRepository(aReviewGroupDir);
			newRepo.create(true);
			newRepo.getConfig().setString("core", null, "sharedrepository", "0666");
			newRepo.getConfig().save();

			return newRepo;
		} catch (IOException e) {
			throw new ReviewsFileStorageException(e);
		}
	}

	/**
	 * @param aReviewGroupDir
	 * @throws ReviewsFileStorageException
	 */
	private Repository openRepository(File aReviewGroupDir) throws ReviewsFileStorageException {
		Repository r;
		try {
			r = FileKey.exact(aReviewGroupDir, FS.DETECTED).open(true);
		} catch (IOException e) {
			throw new ReviewsFileStorageException(e);
		}
		return r;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.mylyn.reviews.r4e.core.rrepo.IBlobRegistry#registerReviewBlob(byte[])
	 */
	public String registerReviewBlob(final byte[] content) throws ReviewsFileStorageException {
		String id = null;
		ObjectId objid = null;
		try {
			objid = fInserter.insert(Constants.OBJ_BLOB, content);
			fInserter.flush();
		} catch (IOException e) {
			//Check if the file has been registered in the repository if yes record the id, log the exception and continue
			//If the id is not registered throw the exception
			id = blobIdFor(content);
			InputStream is = getBlobContent(null, id);

			if (is == null) {
				//The file was not registered in the local repo
				throw new ReviewsFileStorageException(e);
			} else {
				Activator.fTracer.traceError("IOException while registering content however it's already available in the local repository, "
						+ e.getMessage());
				try {
					is.close();
				} catch (IOException ex) {
					Activator.fTracer.traceError("IOException while closing probe stream, " + ex.getMessage());
				}
			}
		} finally {
			fInserter.release();
		}

		if (objid != null) {
			id = objid.getName();
		}

		return id;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#registerReviewBlob(java.io.InputStream)
	 */
	public String registerReviewBlob(final InputStream content) throws ReviewsFileStorageException {
		try {
			return registerReviewBlob(IOUtils.readFully(content));
		} catch (IOException e) {
			throw new ReviewsFileStorageException(e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.mylyn.reviews.r4e.core.rrepo.IBlobRegistry#registerReviewBlob(java.io.File)
	 */
	public String registerReviewBlob(final File aFromFile) throws ReviewsFileStorageException {
		InputStream stream = null;
		try {
			stream = new FileInputStream(aFromFile);
		} catch (FileNotFoundException e) {
			throw new ReviewsFileStorageException(e);
		}

		String id = null;
		ObjectId objid = null;
		try {
			objid = fInserter.insert(Constants.OBJ_BLOB, aFromFile.length(), stream);
			fInserter.flush();
			FileSupportCommandFactory.getInstance().grantWritePermission(fRepository.getDirectory().getAbsolutePath());
		} catch (IOException e) {
			throw new ReviewsFileStorageException(e);
		} finally {
			fInserter.release();

			try {
				stream.close();
			} catch (IOException e) {
				StringBuilder sb = new StringBuilder("Exception: " + e.getMessage());
				Activator.fTracer.traceDebug(sb.toString());
			}

		}

		if (objid != null) {
			id = objid.getName();
		}

		return id;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#getBlobContent(org.eclipse.core.runtime.IProgressMonitor,
	 * java.lang.String)
	 */
	public InputStream getBlobContent(IProgressMonitor monitor, String id) throws ReviewsFileStorageException {
		InputStream resStream = null;

		if (id == null) {
			return null;
		}

		try {
			ObjectId objId = ObjectId.fromString(id);
			resStream = fRepository.open(objId, Constants.OBJ_BLOB).openStream();
		} catch (Exception e) {
			throw new ReviewsFileStorageException(e);
		}

		return resStream;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#getIFileRevision(org.eclipse.core.runtime.IProgressMonitor
	 * , org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion)
	 */
	public IFileRevision getIFileRevision(IProgressMonitor monitor, final R4EFileVersion fileVersion)
			throws ReviewsFileStorageException {
		final String localId = fileVersion.getLocalVersionID();

		// Validation
		if (localId == null) {
			return null;
		}

		try {
			final IPath path = Path.fromPortableString(fileVersion.getRepositoryPath());
			return new FileRevision() {

				public IFileRevision withAllProperties(IProgressMonitor monitor) throws CoreException {
					return this;
				}

				public boolean isPropertyMissing() {
					return false;
				}

				public IStorage getStorage(IProgressMonitor monitor) throws CoreException {
					return getIStorage(null, fileVersion);
				}

				public String getName() {
					return path.lastSegment();
				}
			};

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#getIStorage(org.eclipse.core.runtime.IProgressMonitor,
	 * org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion)
	 */
	//NOTE: Right now, only the full path prepended with the repo path and appended with the localId is used.  If there is a need
	//to get the pure repo path, we could modify or add code to do this.
	public IStorage getIStorage(IProgressMonitor monitor, R4EFileVersion fileVersion) {

		final IPath path = Path.fromPortableString(fileVersion.getRepositoryPath());
		final String localId = fileVersion.getLocalVersionID();

		// Validation
		if (localId == null) {
			return null;
		}

		return new IStorage() {

			@SuppressWarnings("rawtypes")
			public Object getAdapter(Class adapter) {
				return null;
			}

			public boolean isReadOnly() {
				return true;
			}

			public String getName() {
				return path.lastSegment();
			}

			public IPath getFullPath() {
				//bug349739:  Here we first need to prepend the repository name to the artifact path to get the full path to the artifact
				IPath repoPath = new Path(fRepositoryUtil.getRepositoryName(fRepository));
				String pathString = path.toPortableString();
				return repoPath.append(Path.fromPortableString(pathString + " " + localId)); // Append localId to
																								// differentiate
																								// versions in Repo
			}

			public InputStream getContents() throws CoreException {
				try {
					return getBlobContent(null, localId);
				} catch (Exception e) {
					e.printStackTrace();
					throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage()));
				}
			}
		};
	}

	/**
	 * @return
	 */
	public Repository getRepository() {
		return fRepository;
	}

	/**
	 * Convenience method to close the repository data base
	 */
	public void close() {
		fRepository.close();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#blobIdFor(java.io.InputStream)
	 */
	public String blobIdFor(InputStream content) throws ReviewsFileStorageException {
		String id = null;
		try {
			id = blobIdFor(IOUtils.readFully(content));
		} catch (IOException e) {
			throw new ReviewsFileStorageException(e);
		}
		return id;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#blobIdFor(byte[])
	 */
	public String blobIdFor(byte[] content) {
		String id = fInserter.idFor(Constants.OBJ_BLOB, content).getName();
		fInserter.release();

		return id;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#blobIdFor(java.io.File)
	 */
	public String blobIdFor(File aFromFile) throws ReviewsFileStorageException {
		InputStream stream = null;
		try {
			stream = new FileInputStream(aFromFile);
		} catch (FileNotFoundException e) {
			throw new ReviewsFileStorageException(e);
		}

		String id = null;
		ObjectId objid = null;
		try {
			objid = fInserter.idFor(Constants.OBJ_BLOB, aFromFile.length(), stream);
			FileSupportCommandFactory.getInstance().grantWritePermission(fRepository.getDirectory().getAbsolutePath());
		} catch (IOException e) {
			throw new ReviewsFileStorageException(e);
		} finally {
			fInserter.release();

			try {
				stream.close();
			} catch (IOException e) {
				StringBuilder sb = new StringBuilder("Exception: " + e.getMessage());
				Activator.fTracer.traceDebug(sb.toString());
			}
		}

		if (objid != null) {
			id = objid.getName();
		}

		return id;
	}

}
