package com.beijunyi.parallelgit.filesystem;
import java.io.Closeable;
import java.io.IOException;
import java.nio.file.ClosedFileSystemException;
import java.util.concurrent.locks.ReentrantLock;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.beijunyi.parallelgit.filesystem.exceptions.NoBranchException;
import com.beijunyi.parallelgit.filesystem.exceptions.NoHeadCommitException;
import com.beijunyi.parallelgit.filesystem.merge.MergeNote;
import com.beijunyi.parallelgit.utils.RefUtils;
import org.eclipse.jgit.revwalk.RevCommit;
import static org.eclipse.jgit.lib.Constants.R_HEADS;
public class GfsStatusProvider implements AutoCloseable {
private final ReentrantLock lock = new ReentrantLock();
private final GfsFileStore fileStore;
private String branch;
private RevCommit commit;
private MergeNote mergeNote;
private volatile boolean closed = false;
public GfsStatusProvider(GfsFileStore fileStore, @Nullable String branch, @Nullable RevCommit commit) {
this.fileStore = fileStore;
this.commit = commit;
this.branch = branch;
}
public boolean isDirty() throws IOException {
return fileStore.getRoot().isModified();
}
@Nonnull
public Update prepareUpdate() {
return new Update();
}
@Nonnull
public String branch() {
checkClosed();
if(branch == null)
throw new NoBranchException();
return branch.substring(R_HEADS.length());
}
public boolean isAttached() {
return branch != null;
}
@Nonnull
public RevCommit commit() {
checkClosed();
if(commit == null)
throw new NoHeadCommitException();
return commit;
}
public boolean isInitialized() {
return branch != null;
}
@Nullable
public MergeNote mergeNote() {
checkClosed();
return mergeNote;
}
@Override
public synchronized void close() {
if(!closed) closed = true;
}
private void checkClosed() {
if(closed) throw new ClosedFileSystemException();
}
public class Update implements Closeable {
private Update() {
lock.lock();
}
@Override
public void close() {
lock.unlock();
}
@Nonnull
public Update branch(String newBranch) {
checkClosed();
branch = RefUtils.fullBranchName(newBranch);
return this;
}
@Nonnull
public Update detach() {
checkClosed();
branch = null;
return this;
}
@Nonnull
public Update commit(RevCommit newCommit) {
checkClosed();
commit = newCommit;
return this;
}
@Nonnull
public Update mergeNote(MergeNote newMergeNote) {
checkClosed();
mergeNote = newMergeNote;
return this;
}
@Nonnull
public Update clearMergeNote() {
checkClosed();
mergeNote = null;
return this;
}
}
}