#!/usr/bin/perl

use strict;
use warnings;
use IO::File;
use IO::Handle;

my $stdin = new_from_fd IO::Handle fileno (STDIN), "r" || die "can't open stdin";
my $stdout = new_from_fd IO::Handle fileno (STDOUT), "w" || die "can't open stdout";
$stdout->autoflush;
my $stderr = new_from_fd IO::Handle fileno (STDERR), "w" || die "can't open stderr";
$stderr->autoflush;

$stdout->print ("100 Capabilities
Version: 1.0
Single-Instance: true
Local-Only: true

");

sub check_file
{
  my ($uri, $file) = @_;
  my $realfile = "/var/cache/bootstrap/$file";

  if (my @stat = stat $realfile)
  {
    $stdout->print ("201 URI Done
URI: $uri
Filename: $realfile
Size: $stat[7]
");

    my $sha256sum = sum ("sha256sum", $realfile);
    $stdout->print ("SHA256-Hash: $sha256sum\n") if $sha256sum;

    $stdout->print ("\n");

    return 1;
  }
  elsif ($realfile =~ /^(.*)\.(bz2|gz)$/)
  {
    my $altfile = "$1" if stat "$1";
    if ($altfile)
    {
      $stdout->print ("201 URI Done
URI: $uri
Filename: $realfile
Alt-filename: $altfile

");
      return 1;
    }
  }
}

sub sum
{
  my ($tool, $file) = @_;

  my $fh = new IO::File "$tool $file |" || return;
  my ($sum) = split /\s+/, <$fh>;
  return $sum;
}

sub read_msg
{
  my %ret;

  $_ = $stdin->getline;
  exit 0 unless $_;

  chomp;
  return unless $_;

  die "get broken code" unless /^(\d{3})\s+/;

  $ret{code} = $1;

  while (1)
  {
    $_ = $stdin->getline;
    chomp;
    last unless $_;

    die "get broken header in \"$_\"" unless /^(\S+):\s*(.+)$/;

    $ret{$1} = $2;
  }

  return %ret;
}

while (1)
{
  my %msg = read_msg ();

  if ($msg{code} == 600)
  {
    my $uri = $msg{URI};
    $uri =~ m#:([^:]+)$#;
    my $file = $1;
    $file =~ s#/#_#g;

    next if check_file ($uri, $file);

    $uri =~ m#/([^/]+)$#;
    $file = $1;

    next if check_file ($uri, $file);

    $stdout->print ("400 URI Failure
URI: $uri

");
  }
}

