package com.door43.translationstudio.git;
import android.util.SparseArray;
import com.door43.translationstudio.R;
import com.door43.translationstudio.git.tasks.StopTaskException;
import com.door43.translationstudio.git.tasks.repo.RepoOpTask;
import com.door43.translationstudio.AppContext;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.InitCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.StoredConfig;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
/**
* Created by joel on 9/15/2014.
*/
public class Repo {
private static int numRepos;
private static SparseArray<RepoOpTask> mRepoTasks = new SparseArray<RepoOpTask>();
private Git mGit;
private int mId;
private String mLocalPath;
private StoredConfig mStoredConfig;
private Set<String> mRemotes = new HashSet<String>();
/**
* Creates a new repository instance
* @param repositoryPath the path to the repository directory (not including the .git directory)
*/
public Repo(String repositoryPath) {
// automatically generate repo ids
mId = numRepos;
numRepos ++;
// create the directory if missing
File repoPath = new File(repositoryPath);
if(!repoPath.exists()) {
repoPath.mkdir();
}
mLocalPath = repositoryPath;
// initialize new repository
File gitPath = new File(mLocalPath + "/.git");
if(!gitPath.exists()) {
initRepo();
}
}
/**
* Initialize the git repository
*/
private void initRepo() {
InitCommand init = Git.init();
File initFile = new File(getLocalPath());
init.setDirectory(initFile);
try {
init.call();
} catch (GitAPIException e) {
AppContext.context().showException(e, R.string.error_could_not_create_repository);
}
}
/**
* Returns this repository's unique id
* @return
*/
public int getID() {
return mId;
}
/**
* Returns the repository directory
* @return
*/
public File getDir() {
return new File(getLocalPath());
}
public Git getGit() throws IOException {
if (mGit != null) {
return mGit;
} else {
File repoFile = getDir();
mGit = Git.open(repoFile);
return mGit;
}
}
/**
* Returns the local path to the repository
* @return
*/
public String getLocalPath() {
return mLocalPath;
}
public void cancelTask() {
RepoOpTask task = mRepoTasks.get(getID());
if(task == null) {
return;
} else {
task.cancelTask();
removeTask(task);
}
}
public String getBranchName() {
try {
return getGit().getRepository().getFullBranch();
} catch (IOException e) {
AppContext.context().showException(e);
}
return "";
}
public void removeTask(RepoOpTask task) {
RepoOpTask runningTask = mRepoTasks.get(getID());
if (runningTask == null || runningTask != task)
return;
mRepoTasks.remove(getID());
}
public boolean addTask(RepoOpTask task) {
if (mRepoTasks.get(getID()) != null)
return false;
mRepoTasks.put(getID(), task);
return true;
}
public Set<String> getRemotes() {
if (mRemotes.size() > 0)
return mRemotes;
try {
StoredConfig config = getStoredConfig();
Set<String> remotes = config.getSubsections("remote");
mRemotes = new HashSet<String>(remotes);
return mRemotes;
} catch (IOException e) {
e.printStackTrace();
}
return new HashSet<String>();
}
public void setRemote(String remote, String url) throws IOException {
try {
StoredConfig config = getStoredConfig();
Set<String> remoteNames = config.getSubsections("remote");
if (remoteNames.contains(remote)) {
throw new IOException(String.format(
"Remote %s already exists.", remote));
}
config.setString("remote", remote, "url", url);
String fetch = String.format("+refs/heads/*:refs/remotes/%s/*",
remote);
config.setString("remote", remote, "fetch", fetch);
config.save();
mRemotes.add(remote);
} catch (IOException e) {
e.printStackTrace();
}
}
public void deleteRemote(String remote) throws IOException {
StoredConfig config = getStoredConfig();
config.unsetSection("remote", remote);
}
public StoredConfig getStoredConfig() throws IOException {
if (mStoredConfig == null) {
mStoredConfig = getGit().getRepository().getConfig();
}
return mStoredConfig;
}
}