#!/usr/bin/env perl

# Copyright (c) 2015 Christian Jaeger, copying@christianjaeger.ch
# This is free software. See the file COPYING.md that came bundled
# with this file.

use strict;
use warnings;
use warnings FATAL => 'uninitialized';

# find modules from functional-perl working directory (not installed)
use Cwd 'abs_path';
our ($mydir, $myname);

BEGIN {
    my $location = (-l $0) ? abs_path($0) : $0;
    $location =~ /(.*?)([^\/]+?)_?\z/s or die "?";
    ($mydir, $myname) = ($1, $2);
}
use lib "$mydir/../lib";

sub usage {
    print "usage: $myname < file.diff > file-diff.html

  Turn a textual diff as output by `git diff` into HTML format with
  some coloring.

  Uses streaming and hence works with arbitrarily long inputs.
";
    exit(@_ ? 1 : 0);
}

use Getopt::Long;
our $verbose = 0;
GetOptions("verbose" => \$verbose, "help" => sub {usage},) or exit 1;
usage if @ARGV;

use Method::Signatures;
use FP::Stream ":all";
use FP::IOStream ":all";
use PXML::Serialize qw(puthtmlfile);
use PXML::XHTML ":all";
use FP::Ops ":all";
use Chj::xopen "glob_to_fh";

our $lines = fh_to_stream(
    glob_to_fh(*STDIN, "utf-8"),
    the_method("xreadline_chomp"),
    the_method("xclose")
);

our $html = HTML(
    HEAD(
        TITLE($myname),
        META(
            {
                'http-equiv' => "Content-Type",
                content      => "text/html;charset=utf-8"
            }
        ),
        STYLE(
            { type => "text/css" }, '
.diff {
  color: #008;
  border-top: 1px solid;
  margin-top: 20px;
  padding-top: 10px;
}
.meta {
  color: #008;
}
.position {
  color: blue;
}
.add {
  color: green;
}
.del {
  color: red;
}
.context {
  color: black;
}
.other {
  color: orange;
}
'
        ),
        BODY(
            PRE(
                stream_map func($line)
                {
                    DIV(
                        {
                            class => (
                                  $line =~ /^diff /                   ? "diff"
                                : $line =~ /^(index|new|\+\+\+|---) / ? "meta"
                                : do {
                                    my $c = substr $line, 0, 1;
                                    (     $c eq '@' ? "position"
                                        : $c eq '+' ? "add"
                                        : $c eq '-' ? "del"
                                        : $c eq ' ' ? "context"
                                        :             "other")
                                }
                            )
                        },
                        $line
                    )
                },
                $lines
            )
        )
    )
);

puthtmlfile("-", $html);

# TODO: why have `puthtmlfile` to write to magic "-" file as
# filehandle, but do glob_to_fh etc. manipulation?

