#!/usr/bin/env perl6




use v6;
use File::Presence;
use TXN::Parser;
use TXN::Remarshal;




# -----------------------------------------------------------------------------
# main
# -----------------------------------------------------------------------------

# input is from JSON stdin
multi sub MAIN(
    Str:D :i(:input($)) where '-',
    Str:D :if(:input-format($)) where /:i json/,
    Str:D :of(:output-format($)) where /:i txn/,
    Str :o(:$output)
)
{
    my @e = remarshal($*IN.lines.join("\n"), :if<json>, :of<hash>);
    my TXN::Parser::AST::Entry:D @entry = remarshal(@e, :if<hash>, :of<entry>);
    my Str:D $txn = remarshal(@entry, :if<entry>, :of<txn>);
    output($txn, $output);
}

# input is from JSON file
multi sub MAIN(
    Str:D :i(:$input) where *.so,
    Str:D :if(:input-format($)) where /:i json/,
    Str:D :of(:output-format($)) where /:i txn/,
    Str :o(:$output)
)
{
    my Str:D $file = resolve-path($input);
    die unless exists-readable-file($file);
    my @e = remarshal(slurp($file), :if<json>, :of<hash>);
    my TXN::Parser::AST::Entry:D @entry = remarshal(@e, :if<hash>, :of<entry>);
    my Str:D $txn = remarshal(@entry, :if<entry>, :of<txn>);
    output($txn, $output);
}

# input is from TXN stdin
multi sub MAIN(
    Str:D :i(:input($)) where '-',
    Str:D :if(:input-format($)) where /:i txn/,
    Str:D :of(:output-format($)) where /:i json/,
    Str :o(:$output)
)
{
    my TXN::Parser::AST::Entry:D @entry = from-txn($*IN.lines.join("\n"));
    my @e = remarshal(@entry, :if<entry>, :of<hash>);
    my Str:D $json = remarshal(@e, :if<hash>, :of<json>);
    output($json, $output);
}

# input is from TXN file
multi sub MAIN(
    Str:D :i(:$input) where *.so,
    Str:D :if(:input-format($)) where /:i txn/,
    Str:D :of(:output-format($)) where /:i json/,
    Str :o(:$output)
)
{
    my Str:D $file = resolve-path($input);
    die unless exists-readable-file($file);
    my TXN::Parser::AST::Entry:D @entry = from-txn(:$file);
    my @e = remarshal(@entry, :if<entry>, :of<hash>);
    my Str:D $json = remarshal(@e, :if<hash>, :of<json>);
    output($json, $output);
}

# input is from stdin
multi sub MAIN(
    Str :i(:input($)),
    Str :o(:$output),
    Str :if(:$input-format),
    Str :of(:$output-format)
)
{
    my Str:D $remarshal =
        remarshal($*IN.lines.join("\n"), :$input-format, :$output-format);
    output($remarshal, $output);
}

# output is to stdout
multi sub output(Str:D $remarshal, '-')
{
    say $remarshal.trim;
}

# output is to file
multi sub output(Str:D $remarshal, Str:D $output where *.so)
{
    $output.IO.spurt($remarshal, :createonly);
}

# output is to stdout (default)
multi sub output(Str:D $remarshal, Str $?)
{
    say $remarshal.trim;
}

sub resolve-path(Str:D $path where *.so) returns Str:D
{
    ~$path.subst(/^'~/'/, $*HOME ~ '/').IO.resolve;
}




# -----------------------------------------------------------------------------
# usage
# -----------------------------------------------------------------------------

sub USAGE()
{
    constant $HELP = q:to/EOF/;
    Usage:
      txn-remarshal [-h] [-i=<file>] [-o=<file>] -if=<format> -of=<format>

    Options:
      -h, --help
        print this help message
      -i, --input=<file>
        the input source
      -o, --output=<file>
        the output destination
      -if, --input-format=<format>
        the input file format
      -of, --output-format=<format>
        the output file format

    Files:
      /path/to/file
        absolute path to input/output file
      path/to/file
        relative path to input/output file
      -
        stdin/stdout

    Formats:
      json
        JSON
      txn
        TXN
    EOF
    say $HELP.trim;
}

# vim: set filetype=perl6 foldmethod=marker foldlevel=0:
