#!/bin/perl
# everything generator
use strict;
use Template;
use Time::Piece;
use POSIX qw(strftime);

my $outdir = 'out/';

my $template = Template->new({
    INCLUDE_PATH => 'template',
    INTERPOLATE  => 1,
                            }) || die "$Template::ERROR\n";

sub template_write {
    my $content = '';
    $template->process($_[0], $_[2], \$content)
        || die $template->error(), "\n";
    open(my $fh, '>', $_[1]) or die $!;
    print $fh $content;
    close $fh;
}

sub bloog {
    my %d;
    open(my $fh, '<', $_[0]) or die $!;
    chomp($d{'date'}        = <$fh>);
    chomp($d{'author'}      = <$fh>);
    chomp($d{'rss_title'}   = <$fh>);
    chomp($d{'html_title'}  = <$fh>);
    chomp($d{'description'} = <$fh>);
    $d{'pubdate'} = Time::Piece->strptime($d{'date'}, '%Y%m%d')->strftime("%a, %d %b %Y %H:%M:%S %z");
    return (\%d, $fh);
}

sub arrayify {
    my ($name, $dref, $pushref) = @_;
    my %d = %$dref;
    my @push = @{$pushref};
    my $buffer = '';
    $template->process($name, \%d, \$buffer)
        || die $template->error(), "\n";
    push(@push, $buffer);
    return \@push;
}

sub substreq {
    my ($a, $b) = @_;
    return substr($a, 0, length($b)) eq $b;
}

sub chucked {
    my $buffer = $_[0];
    my @paragraph = @{$_[1]};
    my $raw = $_[2];
    if (($buffer =~ /^<pre>/) or ($raw and $buffer =~ /^</)) {
        push(@paragraph, $buffer);
    } else {
        push(@paragraph, "<p>\n" . $buffer . "</p>\n");
    }
    return \@paragraph;
}

sub html_write {
    my ($dref, $fh) = @_;
    my %d = %$dref;
    my @paragraph;
    my $buffer = '';
    my $pre = 0;
    my $rawline = 0;
    while (my $line = <$fh>) {
        chomp(my $short = $line);
        if ($short eq '' && not $pre) {
            @paragraph = @{chucked($buffer, \@paragraph, $rawline)};
            $rawline = 0;
            $buffer = '';
        } elsif (substreq($short, '#+BEGIN_SRC')) {
            $pre = 1;
            $buffer .= "<pre>\n";
        } elsif (substreq($short, '#+END_SRC')) {
            $pre = 0;
            $buffer .= "</pre>\n";
        } elsif (substreq($short, '#+BEGIN_RAW')) {
            $buffer .= substr($line, length('#+BEGIN_RAW '));
        } elsif (substreq($short, '#+END_RAW')) {
            $rawline = 1;
            $buffer .= substr($line, length('#+END_RAW '));
        } else {
            $buffer .= $line;
        }
    }
    @paragraph = @{chucked($buffer, \@paragraph, $rawline, $pre)};
    $d{'paragraph'} = \@paragraph;
    my $content;
    $template->process('article.html', \%d, \$content)
        || die $template->error(), "\n";
    open(my $out, '>', $outdir . $d{'date'} . '.html') or die $!;
    print $out $content;
    close($out);
}

sub main {
    my @rss_items = ();
    my @index_items = ();
    my $last_time = '';

    foreach my $argnum (0 .. $#ARGV) {
        # general data
        my ($dref, $fh) = bloog($ARGV[$argnum]);
        my %d = %$dref;
        if ((($d{'pubdate'} cmp $last_time) == 1) && ($last_time eq '')) {
            $last_time = $d{'pubdate'}
        }
        # rss & index
        @rss_items   = @{arrayify('feed_item.xml', \%d, \@rss_items)};
        @index_items = @{arrayify('index_item.html', \%d, \@index_items)};
        # html page
        html_write(\%d, $fh);
        close($fh);
    }

    template_write('feed.xml', $outdir . 'feed.xml', {
        items => \@rss_items,
        last_time => $last_time,
                   });

    template_write('index.html', $outdir . 'bloog.html', {
        items => \@index_items,
                   });
}

main();
