#!/usr/bin/env perl

use v5.10.1;

use strict;
use warnings;

use Getopt::Long::Descriptive;
use IO::Handle;
use Path::Class;
use Pod::Readme;

=head1 NAME

pod2readme - Intelligently generate a README file from POD

=head1 USAGE

    pod2readme [-cfho] [long options...] input-file [output-file] [target]

        Generate a README file from POD

        -t --target     target type (default: 'readme')
        -f --format     output format (default: 'text')
        -b --backup     backup output file
        -o --output     output filename (default based on target)
        -c --stdout     output to stdout (console)
        -h --help       print usage and exit

=head1 SYNOPSIS

    pod2readme -f markdown lib/MyApp.pm

=head1 DESCRIPTION

This utility will use L<Pod::Readme> to extract a F<README> file from
a POD document.

It works by extracting the POD, and then calling the appropriate
filter program to convert the POD to another format.

=head1 OPTIONS

=head2 C<--backup>

By default, C<pod2readme> will back up the output file. To disable
this, use the C<--no-backup> option.

=head2 C<--output>

Specifies the name of the output file. If omitted, it will use the
second command line argument, or default to the C<--target> plus the
corresponding extention of the C<--format>.

For all intents, the default is F<README>.

=head2 C<--target>

The target of the filter, which defaults to "readme".

=head2 C<--format>

The output format, which defaults to "text".

Other supposed formats are "html", "latex", "man", "markdown", "pod",
"rtf", and "xhtml".

=head2 C<--stdout>

If enabled, it will output to the console instead of C<--output>.

=head2 C<--help>

Prints the usage and exits.

=head1 SEE ALSO

L<pod2text>, L<pod2markdown>.

=cut

my %FORMATS = (
    'html'     => { class => 'Pod::Simple::HTML', },
    'latex'    => { class => 'Pod::Simple::LaTeX' },
    'man'      => { class => 'Pod::Man' },
    'markdown' => { class => 'Pod::Markdown' },
    'pod'      => { class => undef },
    'rtf'      => { class => 'Pod::Simple::RTF' },
    'text'     => { class => 'Pod::Simple::Text' },
    'xhtml'    => { class => 'Pod::Simple::XHTML' },
);

sub validate_format {
    my $value = shift;
    if ( exists $FORMATS{$value} ) {
        return $value;
    }
    else {
        die "Invalid format: '${value}'\n";
    }
}

my ( $opt, $usage ) = describe_options(
    '%c %o input-file [output-file] [target]',
    [],
    ['Generate a README file from POD'],
    [],
    [ 'target|t=s' => "target type (default: 'readme')" ],
    [
        'format|f=s' => "output format (default: 'text')",
        {
            default   => 'text',
            callbacks => { format => \&validate_format },
        }
    ],
    [ 'backup|b!' => "backup output file", { default => 1 } ],
    [ 'output|o' => "output filename (default based on target)" ],
    [ 'stdout|c' => "output to stdout (console)" ],
    [ 'help|h'   => "print usage and exit" ],
);

die $usage if $opt->help;

my %args = ();

if ( my $input = shift @ARGV ) {
    $args{input_file} = $input;
}

my $format = $FORMATS{ $opt->format };
unless ($format) {
    say sprintf( "Unknown format: '\%s'", $opt->format );
    die $usage;
}

my $output = $opt->output || shift @ARGV;
my $target = $opt->target || shift @ARGV || 'readme';

$args{target} = $target;

if ( my $class = $format->{class} ) {
    $args{translation_class} = $class;
}

if ( $opt->stdout ) {
    my $fh = IO::Handle->new;
    if ( $fh->fdopen( fileno(STDOUT), 'w' ) ) {
        $args{translate_to_fh} = $fh;
    }
    else {
        die "Cannot get a filehandle for STDOUT";
    }
}
else {
    $args{translate_to_file} = $output if $output;
}

my $pr = Pod::Readme->new(%args);

$output ||= $pr->translate_to_file;

if ( $opt->backup && $output && -e $output ) {
    file($output)->copy_to( $output . '.bak' );
}

$pr->run();
