#!/usr/bin/perl -T
use XML::Parser;
use Time::Local;

my $in_tag; my $tag;
my $in_desc; my $desc;
my $in_prev; my $prev;
my $in_current; my $current;
my $in_vc; my $vc;

sub get_fields {
	my $content=shift;
	my $xp = new XML::Parser(Handlers => { 
		Char => \&char_handler ,
		Start => \&start_handler,
		End => \&end_handler,
	});

	$xp->parse($content, ProtocolEncoding => 'ISO-8859-1');
	my %fields=(
		tag	=>	$tag,
		desc	=>	$desc,
		prev	=>	$prev,
		visualcode	=>	$vc,
		current	=>	$current);
	return \%fields;
}


sub char_handler {
  my($xp, $data) = @_;
  if ($in_tag) { $tag .= $data; }
  elsif ($in_desc) { $desc .= $data; }
  elsif ($in_prev) { $prev .= $data; }
  elsif ($in_current) { $current .= $data; }
  elsif ($in_vc) { $vc .= $data; }
}
sub start_handler {
  my($xp, $data, @rest) = @_;
  $in_tag=1 if ($data =~ /tag/);
  $in_desc=1 if ($data =~ /desc/);
  $in_prev=1 if ($data =~ /^base.previous$/);
  $in_current=1 if ($data =~ /^base.current$/);
  $in_vc=1 if ($data =~ /^visualcode$/);
}
sub end_handler {
  my($xp, $data) = @_;
  $in_tag=$in_desc=$in_prev=$in_current=$in_vc=0;
}



my %pic_persons=(
	"X/"			=>	"testing",
);

sub response
{
	(my $status, my $msg)=@_;
	print "Content-Type: text/html\n";
	#print "Status: $status\n";
	print "\n";
	print $msg;
	print "\n";
	exit 0;
}

sub urldecode {
	local($val)=@_;
	$val=~s/\+/ /g;
	$val=~s/%([0-9A-Ha-h]{2})/pack('C',hex($1))/ge;
	return $val;
}

if ($ENV{'REQUEST_METHOD'} ne "POST") { &response(201, "Error: Request method is not POST"); }

my $f=$ENV{'QUERY_STRING'};
$f=~/([-a-zA-Z0-9:;_.\/ %()]+)/;
my $arg=$1;
(my $action, my $meta, my $offset, my $filen)=map { urldecode($_) }  split(/;/, $arg);

if ($filen=~/\.\./) {
	&response(500, ".. not allowed in path");
}

if ($filen eq "") { &response(201, "Error: No filen given"); }
$path=$filen;
$path=~s/([^\/]+)$//;

# doesn't seem to work :-(
umask(0007);
$)="9231 9231";

my $person;
if ($meta eq "") {
	$DIR="/home/mraento/public_html/context/upload/";
	if ($action eq "P") {
		&response(200, "OK");
	}
} else {
	$person=$pic_persons{$path};
	&response(500, "uploader not known") unless ( defined($person) );
	$DIR="/home/mraento/public_html/pics/" . $person . "/";
	$path="";
	$filen=~s/.*\/([^\/]+)$/\1/;
	umask(0002);

	my $file_i=0; my $prev_filen; my $curr_filen;
	$filen=~/^(.*)\.([^.]*)$/;
	(my $file_base, my $file_ext)=($1, $2);

	$prev_filen=$curr_filen=$filen;
	while (-f $DIR . $curr_filen) {
		$file_i++;
		$prev_filen=$curr_filen;
		$curr_filen=$file_base . "_" . $file_i . "." . $file_ext;
	}
	if ($action eq "C") {
		$content_filen=$filen=$curr_filen;
	} elsif($action eq "A") {
		$content_filen=$filen=$prev_filen;
	} elsif($action eq "P") {
		$content_filen=$prev_filen;
		$filen=$prev_filen . "_packet.xml";
	}
}

my $input="";

my $debug="";

$ENV{'PATH'}="/bin:/usr/bin";

mkdir($DIR . $path);

if ( (! $meta eq "" ) && $action eq "P" ) {
	while (<STDIN>) {
		$input .= $_;
	}
	my $f=get_fields($input);
	(my $tag, my $desc, my $prev, my $curr, my $vc) = ( $f->{'tag'}, $f->{'desc'}, $f->{'prev'},
		$f->{'current'}, $f->{'visualcode'});
	#$desc=~s/[\r\n]//gs;

	if ($vc eq "") {
		$tag=~/([-a-zA-Z0-9:;_.\/ %()]+)/;
		$tag="Unsorted" if ($tag eq "");
		
		my $indexf; my $ind;
		if ($tag eq "") { $indexf="index.txt"; $ind="Unsorted"; }
		else { $indexf= $tag . ".txt"; $ind=$tag; }
		
		open(OUTI, ">>" . $DIR . $indexf) || &response(201, "Error: cannot open output file ${DIR}${indexf}");
	} else {
		my $prevd=$DIR;
		$DIR="/home/mraento/public_html/pics/vc/";
		$indexf=$vc . ".txt";
		open(OUTI, ">>" . $DIR . $indexf) || &response(201, "Error: cannot open output file ${DIR}${indexf}");
		my $prev_cf;
		$prev_cf=$content_filen;
		$content_filen=$person . "_" . $content_filen;
		$debug="/bin/cp"  . " " . $prevd . $prev_cf . " " .  $DIR . $content_filen;
		system("/bin/cp" , $prevd . $prev_cf,  $DIR . $content_filen);
	}

	my $datetime=$meta;
	$datetime =~ /(....)(..)(..)T(..)(..)(..)/;
	my($year, $mon, $d, $h, $min, $s)=($1, $2, $3, $4, $5, $6);
	my $now=localtime(timelocal($s, $min, $h, $d, $mon-1, $year));

	if ($current eq "") {
		if ($prev eq "") {
			$meta="Unknown";
		} else {
			$meta="prev: $prev";
		}
	} else {
		$meta=$current;
	}
	print OUTI $meta, "\t", $content_filen, "\t", $now, "\t", $desc, "\n";
	#system("mkdir $DIR$tag");
	#system("ln -s $DIR$content_filen $DIR$tag");
	
	close(OUTI);
}

if ($action eq "C" || $action eq "P") {
	open(OUT, ">" . $DIR . $filen) || &response(201, "Error: Cannot open output file $DIR$filen");
} else {
	open(OUT, "+<" . $DIR . $filen) || &response(201, "Error: Cannot open output file $DIR$filen");
	seek(OUT, $offset, 0);
}

print OUT $input;
while (<STDIN>) {
	print OUT $_;
}
close(OUT);

#&response(200, "debug $debug\naction $action\nmeta $meta\ntag $tag\nvc $vc\ncontent filen $content_filen\nOK");
&response(200, "OK");
