package Mojolicious::Command::export;
our $VERSION = '0.001';
# ABSTRACT: Export a Mojolicious website to static files

#pod =head1 SYNOPSIS
#pod
#pod   Usage: APPLICATION export [OPTIONS] [PAGES]
#pod
#pod     ./myapp.pl export
#pod     ./myapp.pl export /perldoc --to /var/www/html
#pod
#pod   Options:
#pod     -h, --help        Show this summary of available options
#pod         --to          Path to store the static pages. Defaults to '.'.
#pod     -q, --quiet       Silence report of dirs/files modified
#pod
#pod =head1 DESCRIPTION
#pod
#pod Export a Mojolicious webapp to static files.
#pod
#pod =head1 SEE ALSO
#pod
#pod L<Mojolicious>, L<Mojolicious::Commands>
#pod
#pod =cut

use Mojo::Base 'Mojolicious::Command';
use Mojo::File qw( path );
use Mojo::Util qw( getopt );

has description => 'Export site to static files';
has usage => sub { shift->extract_usage };

sub run {
    my ( $self, @args ) = @_;
    my %opt = (
        to => '.',
    );
    getopt( \@args, \%opt,
        'to=s',
        'quiet|q' => sub { $self->quiet( 1 ) },
    );

    my $root = path( $opt{ to } );
    my @pages = @args ? map { m{^/} ? $_ : "/$_" } @args : ( '/' );

    my $ua = Mojo::UserAgent->new;
    $ua->server->app( $self->app );

    my %exported;
    while ( my $page = shift @pages ) {
        next if $exported{ $page };
        $exported{ $page }++;
        my $tx = $ua->get( $page );
        my $res = $tx->res;
        my $type = $res->headers->content_type;
        if ( $type and $type =~ m{^text/html} and my $dom = $res->dom ) {
            my $dir = path( $page )->dirname;
            push @pages,
                grep { !$exported{ $_ } } # Prune duplicates
                map { m{^/} ? $_ : $dir->child( $_ )."" } # Fix relative URLs
                grep { !m{^(?:[a-zA-Z]+:)?//} } # Not full URLs
                $dom->find( '[href]' )->map( attr => 'href' )->each,
                $dom->find( '[src]' )->map( attr => 'src' )->each,
                ;
        }

        my $to = $root->child( $page );
        if ( $to !~ m{[.][^/.]+$} ) {
            $to = $to->child( 'index.html' );
        }
        $self->write_file( $to, $tx->res->body )
    }
}

1;

__END__

=pod

=head1 NAME

Mojolicious::Command::export - Export a Mojolicious website to static files

=head1 VERSION

version 0.001

=head1 SYNOPSIS

  Usage: APPLICATION export [OPTIONS] [PAGES]

    ./myapp.pl export
    ./myapp.pl export /perldoc --to /var/www/html

  Options:
    -h, --help        Show this summary of available options
        --to          Path to store the static pages. Defaults to '.'.
    -q, --quiet       Silence report of dirs/files modified

=head1 DESCRIPTION

Export a Mojolicious webapp to static files.

=head1 SEE ALSO

L<Mojolicious>, L<Mojolicious::Commands>

=head1 AUTHOR

Doug Bell <preaction@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2018 by Doug Bell.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
