#!/usr/bin/env raku

use PDF::Lite;

use Text::Utils :ALL;
use Config::TOML;

use PDF::Writer;

my %config; # toml hash
my $cfil = "{%*ENV<HOME>}/.pdfwriter/default.toml";

my $usage = 0;
if not @*ARGS.elems {
    say qq:to/HERE/;
    Usage: {$*PROGRAM.IO.basename} mode [options...] <input text file>

    Modes
      text - Converts the input file's lines to PDF (default)
      pod  - Converts the Raku pod file to PDF using :config
               options. See pod examples in the examples directory.

    Options
      number          - Add line numbers in the left column
      underline       - Stroke each baseline with a thin line
      title[=T]       - Add title to the page number line (default: input file name)
      size=N          - Font size (default: 10)
      font=F          - Font name (default: Courier)
      margins=l,r,t,b - Margins (default: one-inch on all sides)
      paper=T         - Where T is Letter (default), Legal, A4, or A5
      truncate=N      - Where N is the max number of chars on a line
                          and the rest are ignored
      wrap=N          - Where N is the max number of chars on a line
                          and the rest are wrapped to as many lines
                          as needed
      config=F        - Where F is the name of a TOML file other than
                          the default location
      verbose         - See more etails of the execution
      debug           - For developer use

    Notes
      Modes and options may be selected by the minimum number of unique
        leading characters, e.g., 'te' selects 'text' and 'tr' selects
        'truncate'.
      You may enter personal defaults in a TOML file defined at:
        '\$HOME/.pdfwriter/default.toml'
    HERE
    exit
}

my $ifil = @*ARGS.pop;
if not ($ifil.IO.f and $ifil.IO.r) {
    die "FATAL: Input file '$ifil' cannot be read.";
}

my $text      = 1;
my $pod       = 0;
my $debug     = 0;
my $verbose   = 0;
my $toml;

my $doc = Doc.new;

if $cfil.IO.r {
    %config = from-toml :file($cfil);
    note "Found your 'default.toml' file." if $debug;
    if $debug {
        note "DEBUG: Dumping \%config:";
        note %config.raku;
        note "DEBUG early exit";
        exit;
    }
    # extract and set vars
    my $err = 0;
    my $def = %config<default> // ++$err;
    if $err {
        note "WARNING: Cannot find config key: default.";
        note "         You may have unexpected results.";
        exit;
    }
    my %h = %config{$def};
    for %h.kv -> $k, $v {
        note "  $k => '$v'" if $debug;
        given $k {
            when $k eq 'underline' { $doc.underline = $v }
            when $k eq 'leading-ratio' { $doc.leading-ratio = $v }
            when $k eq 'size' { $doc.size = $v }
            when $k eq 'font' { $doc.font = $v }
            default { ++$err; note "Unknown config key: $k" }
        }
    }
    if $err {
        note "WARNING: One or more unknown config keys were found.";
        note "         You may have unexpected results.";
    }
}
else {
    note "No 'default.toml' file was found in your home directory, subdir '.pdfwriter'."
}

for @*ARGS {
    # options
    # doc options (may be defined in the config file)
    when $_.contains(/:i ^u/) { $doc.underline = 1 }
    when $_.contains(/:i ^n/) { $doc.number = 1 }
    when /:i tr <[uncate]>* '=' (\d+) / {
        $doc.truncate = +$0;
    }
    when /:i w <[rap]>* '=' (\d+) / {
        $doc.wrap = +$0;
    }
    when /:i pa <[per]>* '=' (\S+) / {
        $doc.paper = ~$0;
    }
    when /:i st <[tyle]>* '=' (\S+) / {
        $doc.style = ~$0;
    }
    when /:i si <[ze]>* '=' (\S+) / {
        $doc.size = ~$0;
    }
    when /:i w <[eight]>* '=' (\S+) / {
        $doc.weight = ~$0;
    }
    when /:i ti <[tle]>* ['=' (\S+)]? / {
        if $0.defined {
            $doc.title = ~$0;
        }
        else {
            $doc.title = $ifil;
        }
    }
    when /:i m <[argins]>* '=' (\S+) ',' (\S+) ',' (\S+) ',' (\S+) / {
        $doc.left   = +$0;
        $doc.right  = +$1;
        $doc.top    = +$2;
        $doc.bottom = +$3;
    }

    # other options
    when $_.contains(/:i ^v/) { $verbose = 1 }
    when $_.contains(/:i ^d/) { $debug = 1 }
    when /:i c <[onfig]>* '=' (\S+) / {
        $toml = ~$0;
    }

    # modes
    when $_.contains(/:i ^t/) { $text = 1; $pod = 0 }
    when $_.contains(/:i ^p/) { $pod = 1; $text = 0 }

    default { die "FATAL: Unknown arg '$_'" }
}

if $pod {
   die "FATAL: The pod mode is not yet implemented.";
}

# some default settings to get started
# TODO define a page class to hold such things
$doc.height = 11  * 72;
$doc.width  = 8.5 * 72;

$doc.Pdf = PDF::Lite.new;

if $ifil ~~ /:i pdf $/ {
    die "FATAL: Not attempting to read a file with name ending in 'pdf': $ifil ";
}
$doc.title = $ifil;
$doc.ofil = $ifil ~ '.pdf';
if $debug {
   say "DEBUG: infile '$ifil'; outfile '$doc.ofil'";
   exit;
}

# GLOBAL VALUES =====================================
# Set the default page size for all pages
$doc.Pdf.media-box = $doc.paper;

=begin comment
my $pdf = PDF::Lite.new;
my $page = $pdf.add-page;
my $fnam = "Courier";
my $font = $pdf.core-font($fnam);
=end comment

my @lines = $ifil.IO.lines;

text2pdf @lines, :$doc, :$debug;

# Save the new PDF
$doc.Pdf.save-as($doc.ofil);
say "See file '{$doc.ofil}'";
