#!/usr/bin/env perl

# This script generates licence.h (containing the PuTTY licence in the
# form of macros expanding to C string literals) from the LICENCE
# master file. It also regenerates the licence-related Halibut input
# files.

use warnings;
use File::Basename;
use Getopt::Long;

my $usage = "usage: licence.pl (--header|--licencedoc|--copyrightdoc) " .
            "[-o OUTFILE]\n";
my $mode = undef;
my $output = undef;
GetOptions("--header" => sub {$mode = "header"},
           "--licencedoc" => sub {$mode = "licencedoc"},
           "--copyrightdoc" => sub {$mode = "copyrightdoc"},
           "o|output=s" => \$output)
    and defined $mode
    or die $usage;

# Read the input file. We expect to find that alongside this script.
my $infile = (dirname __FILE__) . "/LICENCE";
open my $in, $infile or die "$infile: open: $!\n";
my @lines = ();
while (<$in>) {
    y/\r//d;
    chomp;
    push @lines, $_;
}
close $in;

# Format into paragraphs.
my @paras = ();
my $para = undef;
for my $line (@lines) {
    if ($line eq "") {
        $para = undef;
    } elsif (!defined $para) {
        push @paras, $line;
        $para = \$paras[$#paras];
    } else {
        $$para .= " " . $line;
    }
}

# Get the copyright years and short form of copyright holder.
die "bad format of first paragraph\n"
    unless $paras[0] =~ m!copyright ([^\.]*)\.!i;
$shortdetails = $1;

my $out = "";

if ($mode eq "header") {
    $out .= "/*\n";
    $out .= " * licence.h - macro definitions for the PuTTY licence.\n";
    $out .= " *\n";
    $out .= " * Generated by @{[basename __FILE__]} from $infile.\n";
    $out .= " * You should edit those files rather than editing this one.\n";
    $out .= " */\n";
    $out .= "\n";

    $out .= "#define LICENCE_TEXT(parsep) \\\n";
    for my $i (0..$#paras) {
        my $lit = &stringlit($paras[$i]);
        $out .= "    parsep \\\n" if $i > 0;
        $out .= "    \"$lit\"";
        $out .= " \\" if $i < $#paras;
        $out .= "\n";
    }
    $out .= "\n";

    $out .= sprintf "#define SHORT_COPYRIGHT_DETAILS \"%s\"\n",
        &stringlit($shortdetails);
} elsif ($mode eq "licencedoc") {
    # Write out doc/licence.but.

    $out .= "\\# Generated by @{[basename __FILE__]} from $infile.\n";
    $out .= "\\# You should edit those files rather than editing this one.\n\n";

    $out .= "\\A{licence} PuTTY \\ii{Licence}\n\n";

    for my $i (0..$#paras) {
        my $para = &halibutescape($paras[$i]);
        if ($i == 0) {
            $para =~ s!copyright!\\i{copyright}!; # index term in paragraph 1
        }
        $out .= "$para\n\n";
    }
} elsif ($mode eq "copyrightdoc") {
    # Write out doc/copy.but, which defines a macro used in the manual
    # preamble blurb.

    $out .= "\\# Generated by @{[basename __FILE__]} from $infile.\n";
    $out .= "\\# You should edit those files rather than editing this one.\n\n";

    $out .= sprintf "\\define{shortcopyrightdetails} %s\n\n",
        &halibutescape($shortdetails);
}

my $outfile;
my $opened = (defined $output) ?
    (open $outfile, ">", $output) : (open $outfile, ">-");
$opened or die "$output: open: $!\n";
print $outfile $out;
close $outfile;

sub stringlit {
    my ($lit) = @_;
    $lit =~ s!\\!\\\\!g;
    $lit =~ s!"!\\"!g;
    return $lit;
}

sub halibutescape {
    my ($text) = @_;
    $text =~ s![\\{}]!\\$&!g; # Halibut escaping
    $text =~ s!"([^"]*)"!\\q{$1}!g; # convert quoted strings to \q{}
    return $text;
}

sub write {
    my ($filename, $newcontents) = @_;
    if (open my $fh, "<", $filename) {
        my $oldcontents = "";
        $oldcontents .= $_ while <$fh>;
        close $fh;
        return if $oldcontents eq $newcontents;
    }
    open my $fh, ">", $filename or die "$filename: open: $!\n";
    print $fh $newcontents;
    close $fh;
}