use strict;
use Digest::SHA qw(sha256);
use Math::BaseCalc;
use Math::BigInt;
use POE qw(Wheel::Run Filter::Stream);

$SIG{CHLD} = 'IGNORE';

sub doBase {
   my $calc36 = new Math::BaseCalc(digits=>[2,7,9,"C","D","F","H","K","M","N","P","R","S","T","U","V","W","X"]);
   return $calc36->to_base(Math::BigInt->from_bytes(shift));
}

sub calcKey {
   my $num = shift;
   my $secret = shift;
   return uc($num).doBase(sha256(uc($num).$secret));
}

sub keyForNumber {
   my $num = shift;
   return substr(calcKey(doBase(Math::BigInt->new($num)->to_bytes()), "lk.3nmJz§082-2lb3"), 0, 10);
}


my $wkhtmltopdf = "/usr/bin/wkhtmltopdf";
my $xvfbrun     = "/usr/bin/xvfb-run";
my $cmd = "'".$xvfbrun." -a --server-args=".'"'."-screen 0, 2000x1900x24".'" '.$wkhtmltopdf." -q -s A5 --margin-right 0mm --orientation Landscape  - -"."'";
#my $cmd = "'".$xvfbrun." -a --server-args=".'"'."-screen 0, 1600x1200x24".'" '.$wkhtmltopdf." -q --page-height 160mm --page-width 155mm - -"."'";

my $pwd = `pwd`;
chomp($pwd);
$pwd = "..".$pwd."/";
my $text2 = "";

foreach my $curkey ($ARGV[0]..$ARGV[1]) {
  die
     unless $ARGV[1];
  my $key = keyForNumber($curkey);
  print $curkey." -> ".$key."\n";
  my $curtext = '<html>
  	<link rel="stylesheet" href="%path%ticketserver/pdf/style_BrUms.css" type="text/css">
  	<head>
  	</head>
  	<body>
  		<div class="page">
			<div class="lasche">
				<table>
					<tr><td><img class="logo-small" src="%path%ticketserver/pdf/logo_sw.jpg" alt="CryptoMagic GmbH"></td><td><img class="icon" src="%path%ticketserver/pdf/code.png" alt="Zugangscode"></td><td><h2>%key%</h2></td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td><img class="icon" src="%path%ticketserver/pdf/number.png" alt="BrUms-Nummer"></td><td>%id%</td></tr>
				</table>
			</div>
			<div class="body">
				<div class="header">
					WiFi Barzahlung
				</div>
				<img class="logo-img" src="%path%ticketserver/pdf/logo_sw.jpg" alt="CryptoMagic GmbH"><img class="qr-code" src="https://ovm-adm.login.jetzt/ajax?job=qrcode&moduleversion=3&id=https://login.jetzt/%key%">
				<table>
					<tr height="5px"><td>  </td></tr>
				</table>
				<table>
					<tr><td class="table-left">
						<div class="text"><h1>Anleitung</h1>Rufen Sie Ihren Status ab unter login.jetzt</div><div class="text">Legen Sie den angezeigten Betrag (normal: 10EUR) in den Umschlag.</div><div class="text">Verschlie&szlig;en Sie den Umschlag.</div><div class="text">Geben Sie den BrUms Code in Ihr Ger&auml;t.</div><div class="text">Werfen Sie den Umschlag in den Tresor.</div>
					</td><td class="table-right">
						<div class="text"><h1>How-To</h1>Check your state via login.jetzt</div><div class="text">Put the displayed amount of money (usualy: 10EUR) in this envelope.</div><div class="text">Close the envelope.</div><div class="text">Enter the BrUms Code in your device.</div><div class="text">Put the envelope into the vault.</div>
					</td></tr>
					<tr height="50px"><td></td></tr>
				</table>
				<div class="alert">
					<div class="alert-top">
						Ihre Zugangsdaten
					</div>
					<div class="alert-content">
						<table>
							<tr><td><img class="icon" src="%path%ticketserver/pdf/number.png" alt="BrUms-Nummer"></td><td>BrUms ID:</td><td>%id%</td></tr>
							<tr><td><img class="icon" src="%path%ticketserver/pdf/code.png" alt="Zugangscode"></td><td>BrUms Code:</td><td>%key%</td></tr>
						</table>
					</div>
				</div>
				<table width="100%">
					<tr height="10px"><td></td></tr>
				</table>
				<div class="footer">
					CryptoMagic&nbsp;GmbH,&nbsp;Schwangaustr.&nbsp;2,&nbsp;86163&nbsp;Augsburg https://www.cryptomagic.eu
				</div>
			</div>
		</div>
	</body>
</html>

  ';
   $curtext =~ s,\%path\%,$pwd,gi;
   $curtext =~ s,\%key\%,$key,gi;
   $curtext =~ s,\%id\%,$curkey,gi;
   $text2 .= $curtext;
}

open(HTML, ">", "/var/www/html/out.html") || die($!);
print HTML $text2;
close HTML;

POE::Session->create(
  inline_states => {
    _start           => sub {
       my ($heap) = $_[HEAP];
       eval {
       $heap->{child} = POE::Wheel::Run->new(
          Program      => "/bin/bash",
          ProgramArgs  => [ "-c", $cmd ],
          StdoutEvent  => "output",
          StderrEvent  => "outputerr",
          ErrorEvent   => 'error',
          CloseEvent   => "close",
          StdioFilter  => POE::Filter::Stream->new(),
       );
     };
       my $pid = $heap->{child}->PID;
       $heap->{child}->put($text2); # $key."\n" x 10);
       $poe_kernel->delay("refresh" => 1);
     }, refresh => sub {
       my ($heap) = $_[HEAP];
       $heap->{child}->shutdown_stdin()
          unless $heap->{child}->get_driver_out_octets();
       print "Running...\n";
       $poe_kernel->delay("refresh" => 1);
    }, output => sub {
       my ($heap, $stdout_line, $wheel_id) = @_[HEAP, ARG0, ARG1];
       print "Read ".length($stdout_line)." Bytes\n";
       $heap->{buf} .= $stdout_line;
    }, close => sub {
       my $heap = $_[HEAP];
       open(OUT, ">", "/var/www/html/out.pdf") || die($!);
       print OUT $heap->{buf};
       close OUT;
       print "Wrote ".length($heap->{buf})." Bytes\n";
       $poe_kernel->delay("refresh" => undef);
    }, outputerr => sub {
       my ($heap, $stderr_line, $wheel_id) = @_[HEAP, ARG0, ARG1];
       print "ERR:".$stderr_line."\n";
    }, error  => sub {
       my ($kernel, $heap, $operation, $errnum, $errstr, $wheel_id) = @_[KERNEL, HEAP, ARG0..ARG3];
       print "ERR2:".$errstr."\n";
    }
  }
);

$poe_kernel->run();
