#!/usr/bin/perl

require "/home/pi/smarthome/library.pl";
use utf8::all;

$debug = 0;
$adrfile = "$budir/addresses.csv";
$tmpfile = "$budir/reminder.tmp";
$template = "$budir/birthdaytempl.txt";
$todayM=`date +%Y-%m-%d`; chomp($todayM);
$todayY=`date +%Y`; chomp($todayY);
$nextYear = $todayY+1;
$forecastgap = $birthdayPreview; # how many days in advance birthdays will be listed



# rownr starts with 1, fieldnr starts with 1
# the first row is the caption line
($mode, $rownr) = @ARGV;
printAndDie("usage: $myself <birthday|preview|datacare|forecast> <list|row-nr>
- birthday: fills the birthday template with the data of given csv file row-nr and sends it
- preview: fills the preview template with the data of given csv file row-nr and sends it
- datacare: fills the datacare template with the data of given csv file row-nr and sends it
- forecast: lists all birthdays in the next $forecastgap days. Needs 'list' as second argument
- list: searches the addresses file and lists all row numbers which suit the transfer of the given template. Except for the mode 'forecast', for each match it executes the given mode with the found row number on itself.
") if($rownr!~/\S/ or $mode eq "-h" or $mode eq "-help" or $mode eq "--help");


$maxnr = `cat $adrfile|grep -v '^ *\$'|wc -l|awk '{print \$1}'`;
chomp($maxnr);
$mode = uc($mode);


if($rownr ne "list"){
	printAndDie("ERROR: row number ($rownr) is not a correct number!") if($rownr=~/\D/);
	printAndDie("ERROR: row number ($rownr) must be between 2 and $maxnr!") if($rownr<2 or $rownr>$maxnr);
	printAndDie("ERROR: csv-file $adrfile does not exist!") if(! -f $adrfile);
	printAndDie("ERROR: mode forecast only lists datasets with a birthday in the next days!") if($mode eq "FORECAST");
}


println("- read csv file $adrfile ...") if($debug);
open F, "<:encoding(utf-8)", $adrfile or printAndDie("ERROR: cannot read csv-file $adrfile: $!");
#open(F, "<$adrfile") or printAndDie("ERROR: cannot read csv-file $adrfile: $!");
$lnr = 0; $colnr = ""; @listNrs = ();
while(<F>){
	$lnr++;
	chomp($_);
	$line = trim($_);
	if($lnr==1){
		@fields = split(/\s*;\s*/, uc($line));
		@captions = @fields;
	} else{
		@fields = split(/\s*;\s*/, $line);
		for($f=0;$f<$#fields+1;$f++){
			$caption = uc($captions[$f]);
			$field = trim($fields[$f]);
			$globalvars{$caption} = $field;
			$$caption = $field;
		}
		if($lnr==$rownr and $rownr ne "list"){
			println("- dataset: $FORENAME $SURNAME");
			last;
		}
		if($rownr eq "list"){
			if($mode eq "DATACARE"){
				$datacomplete = 1;
				for($f=0;$f<$#captions+1;$f++){
					$caption = $captions[$f];
					$field = $globalvars{$caption};
					$datacomplete = 0 if($field!~/\S/ or uc($field) eq $caption);
				}
				push(@listNrs, $lnr) if(!$datacomplete);
			} else{
				$thisBirthday = $BIRTHDAY;
				$thisBirthday =~ s/^....\-(\d\d\-\d\d)$/$todayY-$1/;
				$nextBirthday = $thisBirthday;
				$nextBirthday =~ s/$todayY/$nextYear/;
				push(@listNrs, $lnr) if($mode eq "BIRTHDAY" and $thisBirthday eq $todayM);
				if(($mode eq "PREVIEW" or $mode eq "FORECAST") and $BIRTHDAY=~/^....\-\d\d\-\d\d$/){
					$tsToday = date2timestamp($todayM);
					$tsBirthday = date2timestamp($thisBirthday);
					$tsBirthday = date2timestamp($nextBirthday) if($tsBirthday<$tsToday);
					$dayDiff = int(($tsBirthday-$tsToday)/(24*3600));
					push(@listNrs, $lnr) if($mode eq "PREVIEW" and $dayDiff==$NOTICE);
					if($mode eq "FORECAST" and $dayDiff<=$forecastgap){
						push(@forecast, "$FORENAME $SURNAME (${dayDiff}d): $BIRTHDAY");
					}
				}
			}
		}
	}
}
close(F);


# mode list: calls itself with all found ids
if($rownr eq "list"){
	if($mode eq "FORECAST"){ # just print and exit
		for($n=0;$n<$#forecast+1;$n++){
			$fc = $forecast[$n];
			$fd = $1 if($fc=~/(\d\d\-\d\d)$/);
			push(@fdates, $fd . $fc);
		}
		@fdates = sort(@fdates);
		for($n=0;$n<$#fdates+1;$n++){
			println(substr($fdates[$n], 5));
		}
		println("None") if($#forecast<0);
	} else{ # call itself
		for($n=0;$n<$#listNrs+1;$n++){
			$nr = $listNrs[$n];
			println("$0 $mode $nr");
			system("$0 $mode $nr");
		}
	}
	exit;
}



$outtext = "";
println("- read template $template ...");
open F, "<:encoding(utf-8)", $template or printAndDie("ERROR: cannot read template $template: $!");
#open(F, "<$template") or printAndDie("ERROR: cannot read template $template: $!");
$lnr = 0; $colnr = ""; $start = 0;
while(<F>){
	$lnr++;
	chomp($_);
	$line = trim($_);
	if($line=~/TEMPLATE $mode/){
		$start = 1;
		next;
	}
	next if(!$start);
	last if($line eq "EXIT");
	while($line=~/!([a-z0-9_]+):([^!]+)!/i){
		$func = $1;
		$str = $2;
		if(uc($func)=~/RANDOM_([A-Z]+)$/){ # e.g. !RANDOM_QUOTE:"%Quote%" (von %Author%)!
			$kind = $1;
			$arg = "quotes";
			$arg = "bible" if($kind eq "BIBLE");
			$arg = "jokes" if($kind eq "JOKES");
			$tnr = 0;
			($capline, $valline) = getRandomDataOfFile("$budir/$arg.csv");
			@names = split(/\s*;\s*/, $capline);
			@values = split(/\s*;\s*/, $valline);
			for($f=0;$f<$#names+1;$f++){
				$nam = $names[$f];
				$val = $values[$f];
				$val =~ s/,:/;/g;
				$str =~ s/%$nam%/$val/gi;
			}
		}
		if($func=~/DiffYear/){ # e.g. (!DiffYear:%Now%,%Birthday%!?)
			$str =~ s/%([a-z0-9_]+)%/&replaceByGlobalVar($1)/gei;
			($d1, $d2) = split(/,/, $str);
			$y1 = $1 if($d1=~/\b(\d\d\d\d)\b/);
			$y2 = $1 if($d2=~/\b(\d\d\d\d)\b/);
			$str = $y1-$y2;
		}
		$line =~ s/!$func:[^!]+!/$str/;
	}
	$line =~ s/%([a-z0-9_]+)%/&replaceByGlobalVar($1)/gei;
	if($line=~/^\?(.+)?\?/){
		$expression = $1;
		if($expression=~/^(.+)?([\|=])(.+)$/){
			$val1 = uc($1);
			$cond = $2;
			$val2 = uc($3);
			if($cond eq "="){
				if($val2 eq "EMPTY"){
					next if($val1=~/\S/ and !inArray($val1, @captions));
				}
				elsif($val1 ne $val2){
					next;
				}
			} else{ # negative!
				if($val2 eq "EMPTY"){
					next if($val1!~/\S/ or inArray($val1, @captions));
				}
				elsif($val1 eq $val2){
					next;
				}
			}
		}
		elsif($expression=~/^(.+)?~(.+)$/){ # e.g. ?%BIRTHDAY%~XX?- Dein Geburtsjahr
			$val1 = uc($1);
			$val2 = uc($2);
			next if($val1!~/$val2/i);
		}
		$line =~ s/^\?$expression\?//;
	}
	$outtext .= $line ."\n";
}
close(F);

println("- print mail text ...");
open T, '>:encoding(UTF-8)', $tmpfile;
#open(T, ">$tmpfile") or printAndDie("ERROR: cannot write temp file $tmpfile: $!");
#binmode(T, ":utf8");
print T $outtext;
close(T);
println("- send mail text to $recipients ...");
if($debug){
	println("$shdir/sendmail.sh -s \"Herzliche Grüße\" -b $tmpfile");
	system("cat $tmpfile");
} else{
	system("$shdir/sendmail.sh -s \"Herzliche Grüße\" -b $tmpfile");
}
println("DONE");



sub replaceByGlobalVar{
	my $var = shift;
	$var = uc($var);
	return $todayM if($var eq "NOW");
	return $todayY if($var eq "NOWYEAR");
	return $globalvars{$var};
}

sub getRandomDataOfFile{
	my $file = shift;
	my @lines = getLinesOfFile($file, 1);
	my $r = getRandomOfRange(1, $#lines);
	return ($lines[0], $lines[$r]);
}

sub getLinesOfFile{
	my $filename = shift;
	my $onlyNonEmpty = shift;
	$onlyNonEmpty = 0 if($onlyNonEmpty!~/\S/);
	my @lines = ();
	use utf8::all;
	open L, "<:encoding(utf-8)", $filename or die("ERROR: cannot read file $filename: $!");
#	open(F, "<$filename") or die("ERROR: cannot read $filename: $!");
	while(<L>){
		chomp($_);
		push(@lines, $_) if(!$onlyNonEmpty or $_=~/\S/);
	}
	close(L);
	return @lines;
}

