#!/usr/bin/perl -w
#
# Written by Matthias Nott, if you like it, send money. Or beer. Postcards. Or all of it.
#

use strict;

my $action = "";

#
# For adding, you need the actual url. For deleting, it is sufficient to know
# some of the URL.
#
if(@ARGV < 1 || $ARGV[0] eq "help") {
  print "Usage: tmcontrol add|rm|list [target]\n\n";
  print "For adding, you need the actual url, such as\n\n";
  print "  /Volumes/My Passport for Mac\n\n";
  print "or\n\n";
  print "  afp://mnott\@monster.local/TimeMachine%20Backup\n\n";
  print "For deleting, a part of the name or url is sufficient.\n\n";
  print "For running a backup, use run|start|backup as a shorthand for startbackup.\n\n";
  print "For stopping a running backup, use stop as a shorthand for stopbackup.\n\n";
  
  if(@ARGV == 0 || @ARGV >= 1 && $ARGV[0] eq "help" && @ARGV < 2) {
  	open my $help, "tmutil --help|" or die "Error getting tmutil --help: $!\n";
  	while(<$help>) {
  		s/tmutil/tmcontrol/g;
  		print;
  	}
	  exit 1;
  }
}

$action = $ARGV[0] unless @ARGV < 1;

my %locations;

if($action eq "status") {
	print "Latest backups:\n\n";
	system("tmutil listbackups");
	print "\n";
}

if($action eq "add" || $action eq "rm" || $action eq "list") {
	shift;
	%locations = getLocations($action);
	if ("$action" eq "list") { exit; }
	if(@ARGV < 1) {
		die "Missing location target.\n";
	}
	if($action eq "add" || $action eq "rm") {
		my $target = shift;
		if($action eq "rm") {
			delLocation($target);
		} elsif ($action eq "add") {
			addLocation($target);
		}
	}
} elsif ($action eq "start" || $action eq "run" || $action eq "backup") {
	shift;
	system("tmutil startbackup ".join(' ',@ARGV));
} elsif ($action eq "stop") {
	shift;
	system("tmutil stopbackup ".join(' ',@ARGV));
} else {
	system("tmutil ".join(' ',@ARGV));
}


sub addLocation {
	my $loc = shift;
	system("tmutil setdestination -ap \"".$loc."\"");
	%locations = getLocations("list");
  #sudo tmutil setdestination -ap afp://mnott@monster.local/TimeMachine%20Backup
}

sub delLocation {
	my $name = shift;
	
	foreach my $locname (sort keys %locations) {
		my %location = %{$locations{$locname}};
		if ($locname =~ /$name/i || ($location{"kind"} eq "Network" && $location{"url"} =~/$name/i)) {
			if($location{"kind"} eq "Network") {
			  print "Removing $locname on ".$location{"url"}.".\n";
			} else {
			  print "Removing $locname.\n";
			}
			system("tmutil removedestination ".$location{"id"});
		}
	}
	
	%locations = getLocations("list");
}


sub getLocations {
	my %locations;
	my $action=shift;
	
	open my $mounts, "tmutil destinationinfo|" or die "Error reading destination info: $!\n";

	my $name = "";
	while(<$mounts>) {
		if("$action" eq "list") {
			print;
		} else {
			chomp;
			if(/^Name.*?: (.*?)$/) {
				$name = $1;
			} elsif (/^Kind.*?: (.*?)$/) {
				$locations{$name}->{"kind"} = $1;
			} elsif (/^URL.*?: (.*?)$/) {
				$locations{$name}->{"url"} = $1;
			} elsif (/^Mount Point.*?: (.*)$/) {
				$locations{$name}->{"mountpoint"} = $1;
			} elsif (/^ID.*?: (.*)$/) {
				$locations{$name}->{"id"} = $1;
			}
		}
	}
	return %locations;
}
