package app;

import java.io.IOException;
import java.util.Arrays;

import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.MergeResult;
import org.eclipse.jgit.api.PullCommand;
import org.eclipse.jgit.api.PullResult;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.ProgressMonitor;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;

/**
 * Just wrap some git functions to make them more convenient 
 * and standard to use with Boogie
 * @author nhydock
 *
 */
public class GitUtils {
	
	/**
	 * Prepares a clone repository command
	 * @param repo
	 *   URL of the git repository
	 * @param branch
	 *   Specific branch holding the builds of the game
	 * @param downloadDir
	 *   Directory to download the game into
	 * @param monitor
	 *   Progress monitor useful for hooking into the clone cmd and provide useful visual feedback
	 * @return a contained thread for executing and waiting on the command
	 */
	public static Thread cloneRepo(String repo, String branch, FileHandle downloadDir, ProgressMonitor monitor)
	{
		final CloneCommand cmd = Git.cloneRepository()
				.setURI(repo)
				.setBranchesToClone(Arrays.asList("refs/heads/"+branch))
				.setBranch(branch)
				.setDirectory(downloadDir.file());
		if (monitor != null)
			cmd.setProgressMonitor(monitor);
		
		Thread callThread = new Thread(new Runnable(){
			public void run(){
				try {
					cmd.call().close();
				} catch (GitAPIException e) {
					e.printStackTrace();
				}
			}
		});
		return callThread;
	}

	/**
	 * Checks if the git directory for the game exists already
	 * @return
	 */
	public static boolean gitExists()
	{
		FileHandle gitDir = internalToAbsolute(Boogie.GAME_DIR + "/.git");
		return gitDir.exists();
	}
	
	public static FileHandle internalToAbsolute(String file)
	{
		return Gdx.files.absolute(Gdx.files.internal(file).file().getAbsolutePath());
	}
	
	/**
	 * Pulls the latest git information from the specified git download directory
	 * @param gitDir
	 *   Directory where git data for the game is saved
	 * @param branch
	 *   Specific branch that we should be on and pulling from
	 * @param monitor
	 *   JGit progress monitor that can be hooked onto the pull cmd for reponsive feedback
	 * @return
	 *   A generated thread within which the command sit, used to prevent the app from hard stalling while git is downloading
	 * @throws IOException when Git directory can not be found or opened
	 */
	public static Thread pullRepo(final FileHandle gitDir, String branch, final ProgressMonitor monitor) throws IOException
	{
		final Git source = Git.open(gitDir.file());
		final CheckoutCommand checkout = source.checkout().setName(branch);
		final PullCommand pull = source.pull();
		pull.setRemote("origin");
		pull.setRemoteBranchName(branch);
		if (monitor != null)
			pull.setProgressMonitor(monitor);

		Thread callThread = new Thread(new Runnable(){
			public void run(){
				try {
					//first, insure the directory is on the right branch
					checkout.call();
					//then perform a pull on that branches data
					PullResult result = pull.call();
					MergeResult merge = result.getMergeResult();
					Gdx.app.log("Git", ""+merge.getMergeStatus());
					//close the git repository resources when we're done with it
					source.close();
				} catch (GitAPIException e) {
					e.printStackTrace();
				}
			}
		});
		
		return callThread;
	}

	/**
	 * Deletes the entire directory containing game files, in order to allow it to be redownloaded
	 * @return thread that executes deletion
	 */
	public static Thread clean() {
		final FileHandle gitDir = internalToAbsolute(Boogie.GAME_DIR);
		Thread deleteCmd = new Thread(new Runnable(){
			public void run(){
				gitDir.deleteDirectory();
			}
		});
				
		return deleteCmd;
	}
}

@@ -399,16 +399,58 @@
 Monitor;
+%0Aimport org.eclipse.jgit.lib.StoredConfig;
 %0A%0Aimport
@@ -1133,16 +1133,22 @@
 ng repo,
+ final
  String 
@@ -1549,18 +1549,242 @@
 %09%09%09%09
-cmd.call()
+Git src = cmd.call();%0A%09%09%09%09%09%0A%09%09%09%09%09StoredConfig config = src.getRepository().getConfig();%0A%09%09%09%09%09config.setString(%22remote%22, %22origin%22, %22fetch%22, %22+refs/heads/%22 + branch + %22:refs/remotes/origin/%22 + branch);%0A%09%09%09%09%09config.save();%0A%09%09%09%09%09%0A%09%09%09%09%09src
 .clo
@@ -1781,32 +1781,37 @@
 %09%09%09src.close();%0A
+%09%09%09%09%0A
 %09%09%09%09%7D catch (Git
@@ -1815,32 +1815,46 @@
 GitAPIException 
+%7C IOException 
 e) %7B%0A%09%09%09%09%09e.prin

Improve pull speeds by limiting git remote to only a specific branch