#!/usr/bin/perl -w

use strict;
use warnings;

use LWP::Simple;
use HTTP::Status;
use Data::Dumper;

# Get busy ports
sub busyports($) {
	my $href = shift;

	open(NS, "netstat -an |") || die "Unable to run netstat: $!";
	# Tracker uses UDP, but lets flag all busy ports and avoid overlap
	while(<NS>) {
		if(/(0\.0\.0\.0|::):(\d+)/) {
			$href->{$2} = 1;
		}
	}
	close(NS) || die "Failed to run netstat: $!";
}

sub domirror($$) {
	my $src = shift;
	my $dst = shift;

	# Debug
	print "domirror: $src -> $dst\n";

	eval {
		my $rc = mirror($src, $dst);
		die "$rc" if is_error($rc);
	};
	if($@) {
		warn "$src: $@";
	}
	warn "$dst: 0 bytes" unless(-s $dst);
}

my $rtorrent="rtorrent";
my $dhtnodes="bttracker.debian.org:6881";
my $HOME=$ENV{'HOME'};
my $torrentdir="$HOME/torrents/";
my $versiondir=$ARGV[0];

die "No version directory!\n" unless($versiondir && -d $versiondir);

my $dhtstart = 8500;

my @d=split '/',$versiondir;
my $vnr = $d[$#d];
$torrentdir=$torrentdir.$d[$#d];

opendir DEBCD,$versiondir or die "open: $versiondir: $!\n";
my @arches=readdir(DEBCD);
closedir DEBCD;

chomp $torrentdir;
print `mkdir -p $torrentdir` unless -d "$torrentdir";

mkdir "$torrentdir/.lock" || die "Update already in progress: $!";

@arches = ("amd64","i386",@arches);

my %archdone;
foreach $a (@arches) {
	next if $a eq ".";
	next if $a eq "..";
	next if($archdone{$a});
	$archdone{$a} = 1;
	my $adir = "$versiondir/$a";
	my $fdir = $adir;
	$fdir =~ s|/export/ftp/|http://ftp.acc.umu.se/|;
	$fdir =~ s|/import/ftp/|http://ftp.acc.umu.se/|;
	my @isos = ();
	my $i;
	my $cd;
	my $iso;
	my $rc;
	my $foundisos;
	print "Arch: $a\n";
	foreach $cd ('cd','dvd','hybrid','hdd') {
	    foreach $iso ('iso','usb') {
		if (opendir ISODIR,"$adir/$iso-$cd" ) {
		    print `mkdir "$torrentdir/$a.$iso-$cd"` unless -d "$torrentdir/$a.$iso-$cd";
		    $foundisos=0;
		    @isos = readdir(ISODIR);
		    closedir ISODIR;
		    foreach $i (@isos) {
			next unless (($i =~ ".*iso\$") or ($i =~ ".*img\$"));
			$foundisos=1;
			domirror("$fdir/$iso-$cd/$i", "$torrentdir/$a.$iso-$cd/$i");
			domirror("$fdir/bt-$cd/$i.torrent", "$torrentdir/$a.$iso-$cd/$i.torrent");
			print `perl $HOME/bin/rtorrent_fast_resume.pl $torrentdir/$a.$iso-$cd/ < $torrentdir/$a.$iso-$cd/$i.torrent > $torrentdir/$a.$iso-$cd/$i.torrent.new`;
			print `mv -f $torrentdir/$a.$iso-$cd/$i.torrent.new $torrentdir/$a.$iso-$cd/$i.torrent`;
			print `$HOME/bin/dht-addnodes.pl -f $torrentdir/$a.$iso-$cd/$i.torrent $dhtnodes`;
		    }
		    if($foundisos) {

			foreach (`screen -ls`) {
			    chomp;
			    if($_ =~ /^\s+(\d+).$vnr.$a.$iso-$cd\s+/) {
				my $ppid=$1;
				print "KILL: $_\n";
				# AIX
				#open(PIDS, "ps -T $ppid -o pid= |") || die "open ps: $!";
				# Linux
				open(PIDS, "ps -o pid= --ppid=$ppid |") || die "open ps: $!";
				foreach my $p (<PIDS>) {
				    chomp $p;
				    next if $p eq $ppid;
				    print "  CHILD PID: $p\n";
				    kill 15, $p;
				}
				close(PIDS) || die "ps failed: $!";
				kill 15, $ppid;
				sleep(1);
			    }
			}
			my %bp;
			busyports(\%bp);
			my $dport;
			for($dport = $dhtstart; $bp{$dport}; $dport++) {
# Empty loops are fun?
			}
			$dhtstart = $dport;
			$bp{$dport} = 1;
			my $sessdir="$HOME/.rtorrentsession/$dport";
			if(! -d $sessdir) {
			    mkdir $sessdir;
			}
			print `rm -f $sessdir/*.torrent*`;
					       my $cmd="screen -d -m -S $vnr.$a.$iso-$cd $rtorrent -d $torrentdir/$a.$iso-$cd/ -s $sessdir -O dht=on -O dht_port=$dport $torrentdir/$a.$iso-$cd/*.torrent &";
					       print "$cmd\n";
					       print `$cmd`;
					       }
					       }
					       }
					       }
}
rmdir "$torrentdir/.lock" || warn "Unlock failed: $!";
