#!/usr/bin/env perl
BEGIN {
  $ENV{MOJO_WEBPACK_DEBUG} //= $ENV{MORBO_VERBOSE} // 0;
  $ENV{MOJO_WEBPACK_LAZY} = 1;
  $ENV{MOJO_WEBPACK_RUN}  = 1;

  # Ugly hack to prevent Mojo::Server::Morbo from exiting
  my $worker = $$;
  *CORE::GLOBAL::exit = sub { $worker == $$ ? $_[0] : CORE::exit $_[0] };
}

package    # hide from pause
  Mojo::Server::Webpack;
use Mojo::Base 'Mojo::Server::Morbo';

use Mojo::Server::Morbo;
use Mojo::Util qw(extract_usage getopt);

sub parse_argv {
  my ($self, @args) = @_;

  getopt \@args,
    'b|backend=s' => \$ENV{MOJO_MORBO_BACKEND},
    'h|help'      => \my $help,
    'l|listen=s'  => \my @listen,
    'm|mode=s'    => \$ENV{MOJO_MODE},
    'v|verbose'   => \$ENV{MORBO_VERBOSE},
    'w|watch=s'   => \my @watch;

  die extract_usage if $help or !(my $app = shift @args);

  $self->backend->watch(\@watch)  if @watch;
  $self->daemon->listen(\@listen) if @listen;

  return ($self, $app, @args);
}

sub run {
  my ($self, $app, @args) = shift->parse_argv(@_);

  # Start webpack daemon in worker
  die "Can't fork: $!" unless defined(my $webpack_pid = fork);
  unless ($webpack_pid) {
    local $ENV{MOJO_WEBPACK_RUN} = '--watch';
    Mojo::Server->new->load_app($app);
    exit $!;
  }

  # Manager
  warn "[Webpack] Webpack has pid $webpack_pid.\n" if $ENV{MORBO_VERBOSE};
  $self->SUPER::run($app, @args);

  warn "[Webpack/$$] Reaping webpack with pid $webpack_pid...\n" if $ENV{MORBO_VERBOSE};
  1 while kill $webpack_pid;
}

return __PACKAGE__ if defined wantarray;
__PACKAGE__->new->run(@ARGV);

=encoding utf8

=head1 NAME

crushinator - Mojolicious HTTP, WebSocket and Webpack development server

=head1 SYNOPSIS

  Usage: crushinator [OPTIONS] [APPLICATION]

    crushinator ./script/my_app
    crushinator ./myapp.pl
    crushinator -m production -l https://*:443 -l http://[::]:3000 ./myapp.pl
    crushinator -l 'https://*:443?cert=./server.crt&key=./server.key' ./myapp.pl
    crushinator -w /usr/local/lib -w public -w myapp.conf ./myapp.pl

  Options:
    -b, --backend <name>           Morbo backend to use for reloading, defaults
                                   to "Poll"
    -h, --help                     Show this message
    -l, --listen <location>        One or more locations you want to listen on,
                                   defaults to the value of MOJO_LISTEN or
                                   "http://*:3000"
    -m, --mode <name>              Operating mode for your application,
                                   defaults to the value of
                                   MOJO_MODE/PLACK_ENV or "development"
    -v, --verbose                  Print details about what files changed to
                                   STDOUT
    -w, --watch <directory/file>   One or more directories and files to watch
                                   for changes, defaults to the application
                                   script as well as the "lib" and "templates"
                                   directories in the current working
                                   directory

=head1 DESCRIPTION

Start L<Mojolicious> and L<Mojolicious::Lite> applications with the
L<Mojo::Server::Morbo> web server.

=head1 SEE ALSO

L<Mojolicious::Plugin::Webpack>

=cut
