#!/usr/bin/perl

# online: https://service.stuttgart.de/lhs-services/aws/abfuhrtermine, select date range, ctrl+a, ctrl+c, paste into txt file (e.g. AWS-Abfallkalender_2022.txt)
# or (not sure): the pdf file opened in Word, converted as txt
# but replace german umlaute by ae/oe/ue/ss/Ae/Oe/Ue, and save txt as ANSI

# settings
$debug = 0;
$thisyear = `date +%Y`; chomp($thisyear);
$file = "/home/pi/bubu/AWS-Abfallkalender_$thisyear.txt";
$myself = $0;
$searchmax = 28; # how many days to search at maximum
$icsoutdir = "/home/pi/bubu/TRASH";
$entrynr = 0;
$icsdstart = "050000Z";
$icsdend = "053000Z";

# get arguments
shift if($ARGV[0] eq "trash");
$trashdate = $ARGV[0];
if($trashdate!~/\S/ or $trashdate eq "-h" or $trashdate eq "-help" or $trashdate eq "--help"){
	println("usage: $myself <today|tomorrow, daygap (1=tomorrow...) or date in YYYY-MM-DD or 'next'|ics> [rest|yellow|bio|paper]");
	exit 0;
}
$kind = "";
@args = ();
$icsmode = 0;
for($a=0;$a<$#ARGV+1;$a++){
	if($ARGV[$a] eq "ics"){
		$icsmode = 1;
	} else{
		push(@args, $ARGV[$a]);
	}
}
for($i=$#args;$i>=0;$i--){
	$a = $args[$i];
	$a = lc($a);
	if($a eq "rest" or $a eq "yellow" or $a eq "bio" or $a eq "paper" or $a eq "trash"){
		$kind = $a;
		splice(@args, $i, 1);
	}
}
$trashdate = join(" ", @args);
$trashdate = "next" if($trashdate!~/\S/);
if($icsmode){
	$trashdate = "$thisyear-12-31";
}



# main: check a certain date for trash entries
$today = `date +%Y-%m-%d`;
chomp($today);
$todayts = date2timestamp($today);

# if query is next, call yourself recursively until you found a date
if($trashdate eq "next"){
	$startts = $todayts;
	$try = 0; $found = 0;
	while($try<$searchmax){
		$result = `perl $myself $try`;
		chomp($result);
		if($result ne "nothing"){
			@kinds = split(/\s+and\s+/, $result);
			$isok = 0;
			if($kind!~/\S/){
				$isok = 1;
			} else{
				foreach $k(@kinds){
					$isok = 1 if($k eq $kind);
				}
			}
			if($isok){
				$span = "today";
				$span = "tomorrow" if($try==1);
				if($try>1){
					$dayts = $startts + 24*3600*$try;
#					$try--;
					$daydate = timestamp2date($dayts);
					$dayweek = lc(getWeekday($daydate));
					$dayweek = "sunday" if($dayweek eq "su");
					$dayweek = "monday" if($dayweek eq "mo");
					$dayweek = "tuesday" if($dayweek eq "tu");
					$dayweek = "wednesday" if($dayweek eq "we");
					$dayweek = "thursday" if($dayweek eq "th");
					$dayweek = "friday" if($dayweek eq "fr");
					$dayweek = "saturday" if($dayweek eq "sa");
					if($try<7){
						$span = "next $dayweek, in $try days";
					} elsif($try==7){
						$span = "in 1 week";
					} else{
						$span = "at $dayweek in $try days";
					}
				}
				println("$span: $result");
				$found = 1;
				exit 0;
			}
		}
		$try++;
	}
	if(!$found){
		println("nothing in the next $searchmax days");
		exit 0;
	}
}

# get the desired trashdate
$datets = $todayts;
if($trashdate=~/^\d\d\d\d\-\d\d\-\d\d/){
	$datets = date2timestamp($trashdate);
} elsif($trashdate eq "tomorrow"){
	$datets += 24*3600;
} elsif($trashdate=~/^\d+/){
	$datets += 24*3600*$trashdate;
}
$trashdate = timestamp2date($datets);
$wday = getWeekday($trashdate);
println("- desired date: $trashdate - it's a $wday") if($debug);


# go through file
println("- read file $file ...") if($debug);
open(F, "<$file") or die("ERROR: cannot read file $file: $!");
while(<F>){
	chomp($_);
	$line = trim($_);
	$typ = "R" if($line=~/Rest[ma][ub][ef]a?ll/i);
	$typ = "B" if($line=~/Bio[mg]u[te]l*/i or $line=~/Bioabfall/);
	$typ = "P" if($line=~/Altpapier/i);
	$typ = "Y" if($line=~/Gelber/i);
	if($line=~/^(\w+)\s+(\d\d)\.(\d\d)\.(\d\d\d\d)\s+/){
		$dkey = "$4-$3-$2";
		$dates{$dkey} .= " " if(exists($dates{$dkey}));
		$dates{$dkey} .= $typ;
		println("- \$dates{$dkey}: ". $dates{$dkey}) if($debug);
	}
}
# in case we have Thursday, bio trash, (which is not mentioned in the text file, only by a single !), we have to search in the neighbours
@dkeys = sort(keys(%dates));
$trashdateId = -1;
for($d=0;$d<$#dkeys+1;$d++){
	$dkey = $dkeys[$d];
	createIcsFile($dkey, $dates{$dkey}) if($icsmode and $dates{$dkey}=~/\S/);
	if($dkey eq $trashdate){
		$trash = trim($dates{$dkey});
		$trashdateId = $d;
		println("- $dkey: $trash") if($debug); # debugging
		last;
	}
}
# interprete trash result
$yellow = 0; $yellow = 1 if($trash=~/Y/);
$paper = 0; $paper = 1 if($trash=~/P/);
$rest = 0; $rest = 1 if($trash=~/R/);
$bio = 0; $bio = 1 if($trash=~/B/);


# output preparation
@kinds = ();
push(@kinds, "rest") if($rest or $kind eq "trash");
push(@kinds, "paper") if($paper or $kind eq "trash");
push(@kinds, "yellow") if($yellow or $kind eq "trash");
push(@kinds, "bio") if($bio or $kind eq "trash");
if($#kinds<0){
	println("nothing");
} else{
	println(join(" and ", @kinds));
}



### functions ###
sub createIcsFile{
	my $date = shift;
	$date =~ s/\D//g;
	my $trash = shift;
	$trash = trim($trash);
	my @trashs = split(/\s+/, $trash);
	my @kinds = ();
	foreach my $t(@trashs){
		push(@kinds, "Bio") if("$t" eq "!");
		push(@kinds, "Rest") if("$t" eq "2");
		push(@kinds, "Paper") if("$t" eq "P");
		push(@kinds, "Yellow") if("$t" eq "Y");
	}
	foreach my $kind(@kinds){
		$entrynr++;
		my $enr = $entrynr;
		$enr = "0$enr" if($enr<10);
		my $cfile = "$icsoutdir/entry.$enr.$kind.$date.ics";
		my $uid = "$date.simon.bruegmann\@gmail.com";
		my $stamp = $date ."T". $icsdstart;
		my $begin = $date ."T". $icsdstart;
		my $end = $date ."T". $icsdend;
		my $topic = "Waste $kind";
		println("- print ics file $cfile ...");
		open(C, ">$cfile") or die("ERROR: coulnd't create ics file $cfile: $!");
		print C "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
BEGIN:VEVENT
UID:$uid
DTSTAMP:$stamp
DTSTART:$begin
DTEND:$end
SUMMARY:$topic
LOCATION:Private
END:VEVENT
END:VCALENDAR";
		close(C);

	}
}
sub println{
	my $msg = shift;
	print $msg ."\n";
}
sub trim{
	my $msg = shift;
	$msg =~ s/^\s+//;
	$msg =~ s/\s+$//;
	return $msg;
}
sub timestamp2date{
	my $datets = shift;
	my ($tsec, $tmin, $thour, $tday, $tmon, $tyear) = localtime($datets);
	$tmon = d2($tmon+1); $tyear += 1900; $tday = d2($tday);
	return "$tyear-$tmon-$tday";
}
# convert a date [YY]YY-MM-DD [hh:ss:[mm]] to a timestamp
sub date2timestamp{
	my $datetime = shift;
	$datetime .= " 00:00:00" if($datetime=~/^\d+\-\d{2}\-\d{2}$/);
	my @elems = split(/\s+/, $datetime);
	my $time = pop(@elems);
	$time = trim($time);
	$time = "00:00" if($time!~/\S/);
	$time .= ":00" if($time=~/^\d\d:\d\d$/);
	my @timeelems = split(/:/, $time);
	my $hour = d2($timeelems[0]);
	my $minute = d2($timeelems[1]);
	my $second = d2($timeelems[2]);
	my $date = date2mysql(join(" ", @elems));
	my($year, $month, $day) = split(/\-/, $date);
	$year = "20$year" if(length($year)==2 and $day=~/\S/);
	if($day!~/\S/){
		$day = $month;
		$month = $year;
		my ($tsec, $tmin, $thour, $tday, $tmon, $tyear) = localtime(time);
		$year = $tyear;
	}
	use Time::Local;
	$month--;
	timelocal("$second","$minute","$hour",$day,$month,$year);
}
sub d2{
	my $number = shift;
	return "0$number" if($number<10);
	return $number;
}

sub getWeekday{
	my $date = shift;
	my $mode = shift;
	$mode = "en" if($mode!~/\S/);
	my @weekdays = ("Su", "Mo", "Tu", "We", "Th", "Fr", "Sa");
	@weekdays = ("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa") if($mode eq "de");
	$timestamp = date2timestamp(date2mysql($date));
	my ($sec, $min, $hour, $mday, $month,
    $year, $wday, $yday, $summertime) = localtime($timestamp);
	return $weekdays[$wday];
}
sub date2mysql{
	my $val = shift;
	my $date = "";
	$val = trim($val);
	$date = "$3-$2-$1" if($val=~/^(\d\d)\.(\d\d)\.(\d\d\d\d)/);
	$date = "$1-$2-$3" if($val=~/^(\d\d\d\d)\-(\d\d)\-(\d\d)/);
	$date = "$3-$2-$1" if($val=~/^(\d\d)\/(\d\d)\/(\d\d\d\d)/);
	$date = "$3-$2-$1" if($val=~/^(\d\d)\-(\d\d)\-(\d\d\d\d)/);
	if($val=~/(\d+)[stndrh\.]{0,2}\s*(\w{3,10})\s*(\d\d\d\d)/i or $val=~/(\d\d\d\d)\s*(\w{3,10})\s*(\d+)\s*[stndrh\.]{0,2}/i){
		my $day = trim($1);
		my $mname = trim($2);
		my $year = trim($3);
		if($day=~/\d{4}/){
			my $tmp = $year;
			$year = $day;
			$day = $tmp;
		}
		$mnr = 1;
		$mnr = 2 if($mname=~/feb/i);
		$mnr = 3 if($mname=~/m[a.]r/i);
		$mnr = 4 if($mname=~/apr/i);
		$mnr = 5 if($mname=~/ma[yi]/i);
		$mnr = 6 if($mname=~/jun/i);
		$mnr = 7 if($mname=~/jul/i);
		$mnr = 8 if($mname=~/aug/i);
		$mnr = 9 if($mname=~/sep/i);
		$mnr = 10 if($mname=~/o[ck]t/i);
		$mnr = 11 if($mname=~/nov/i);
		$mnr = 12 if($mname=~/de[cz]/i);
		$date = "$year-". d2($mnr) ."-$day";
	}
	return $date;
}
