package markphip;

import java.io.File;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.subversion.javahl.ClientException;
import org.apache.subversion.javahl.ISVNClient;
import org.apache.subversion.javahl.SVNClient;
import org.apache.subversion.javahl.callback.LogMessageCallback;
import org.apache.subversion.javahl.types.ChangePath;
import org.apache.subversion.javahl.types.Depth;
import org.apache.subversion.javahl.types.Mergeinfo.LogKind;
import org.apache.subversion.javahl.types.Revision;

public class TestMergeInfo {
	
	public void run() {
		String base = "http://svn.apache.org/repos/asf/subversion";
		String branch = base + "/branches/1.7.x/subversion/bindings/javahl";
		String trunk = base + "/trunk/subversion/bindings/javahl";
		String wc = "/Users/markphip/test1";
		Revision rev = new Revision.Number(1154548);
		ISVNClient client = new SVNClient();
		
		try {
			System.out.println("svn co " + branch + " " + wc);
			client.checkout(branch, wc, rev, Revision.HEAD, Depth.infinity, false, true);
			Set<String> revProps = new HashSet<String>();
			revProps.add("svn:author");
			revProps.add("svn:date");
			revProps.add("svn:log");
			Callback callback = new Callback();
			System.out.println("svn mergeinfo --show-revs=eligible " + trunk + " " + wc);
			// When this boolean is set to true, we do not get back valid results
			boolean discoverChangedPaths = true;
			client.getMergeinfoLog(LogKind.eligible, wc, rev, trunk, rev, discoverChangedPaths, Depth.infinity, revProps, callback);
		} catch (ClientException e) {
			e.printStackTrace();
		}
		System.out.println("Done. If there were no revisions printed then there is a bug.");
		if (!deleteDir(new File(wc)))
			System.out.println("Failed to delete test working copy - " + wc);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		TestMergeInfo test = new TestMergeInfo();
		test.run();
	}
	
	// Deletes all files and subdirectories under dir.
	// Returns true if all deletions were successful.
	// If a deletion fails, the method stops attempting to delete and returns false.
	public boolean deleteDir(File dir) {
	    if (dir.isDirectory()) {
	        String[] children = dir.list();
	        for (int i=0; i<children.length; i++) {
	            boolean success = deleteDir(new File(dir, children[i]));
	            if (!success) {
	                return false;
	            }
	        }
	    }

	    // The directory is now empty so delete it
	    return dir.delete();
	}
	
	
	private class Callback implements LogMessageCallback {
		
		@Override
		public void singleMessage(Set<ChangePath> changedPaths, long revision,
				Map<String, byte[]> revprops, boolean hasChildren) {
			if (changedPaths == null)
				System.out.println(revision + " " + new String(revprops.get("svn:author")));
			else
				System.out.println(revision + " " + new String(revprops.get("svn:author")) +
					" " + changedPaths.size() + " paths changed.");
		}

	}
}
