#!/usr/bin/perl
use strict;
use lib "lib";
use Cwd;
use Getopt::Long;
use Plack::Loader;
use Plack::Util;
use Pod::Usage;

my $app    = "app.psgi";
my $env    = "development";
my $help   = 0;
my @includes;

# From 'prove': Allow cuddling the paths with the -I
@ARGV = map { /^(-I)(.+)/ ? ($1,$2) : $_ } @ARGV;

Getopt::Long::Configure("no_ignore_case", "pass_through");
GetOptions(
    "a|app=s"      => \$app,
    "s|server=s"   => \$ENV{PLACK_SERVER},
    "i|impl=s"     => sub { warn "-i is deprecated. Use -s instead\n"; $ENV{PLACK_SERVER} = $_[1] },
    "E|env=s"      => \$env,
    'I=s@'         => \@includes,
    "h|help",      => \$help,
);

pod2usage(0) if $help;
lib->import(@includes) if @includes;

my $handler = Plack::Util::load_psgi $app;

if ($env eq 'development') {
    require Plack::Middleware::StackTrace;
    require Plack::Middleware::AccessLog;
    $handler = Plack::Middleware::StackTrace->wrap($handler);
    $handler = Plack::Middleware::AccessLog->wrap($handler, logger => sub { print STDERR @_ });
}

my @args = map {
    my $is_long_opt = s/^--//;
    my @v = split '=', $_, 2;
    $v[0] =~ tr/-/_/ if $is_long_opt;
    @v;
} @ARGV;

my $server = Plack::Loader->auto(@args);
$server->run($handler);

__END__

=head1 NAME

plackup - Run PSGI application with Plack servers

=head1 SYNOPSIS

  # read your app from app.psgi file
  plackup

  # can be passed with --app option (Or -a)
  plackup --app hello.psgi

  # Switch server implementation with --server (or -s)
  plackup --server Coro --port 9090

=head1 DESCRIPTION

plackup is a command line utility to run PSGI application from the command line.

plackup automatically figures out the environment it is run in, and
runs your application in that environment. FastCGI, CGI, AnyEvent and
others can all be detected. See L<Plack::Loader> for the authorative
list.

C<plackup> assumes you have an C<app.psgi> script in your current
directory, that would look like:

  #!/usr/bin/perl
  use MyApp;
  my $app = MyApp->new;
  my $handler = sub { $app->run_psgi(@_) };

The last statement of C<app.psgi> should be a code reference that is a
PSGI application.

=head1 OPTIONS

=over 4

=item -a, --app

Use the C<--app> option to locate a C<.psgi> script with a different
name in a different path. (Actually the path doesn't need to end in
C<.psgi>: it's just there for convention)

=item -s, --server

Select a specific implementation to run on using the C<PLACK_SERVER>
environment variable or use the C<-s> or C<--server> flag which will
be prefered over the environment variable if present.

=item -I

Specify perl library include path, like C<perl>'s -I option.

=item -E, --env

Specify the environment option (default is C<development>). If it's
set to C<development>, following middleware is enabled by default:
L<CommonLogger>, L<StackTrace>.

=back

=head1 SEE ALSO

L<Plack::Loader>

=cut
