#!/usr/bin/env perl6

use overwatch;

sub MAIN (
  *@args, 
  Str :e(:$execute) = 'perl6', 
  Bool :k(:$keep-alive) = True, 
  Bool :x(:$exit-on-error) = False, 
  Int  :g(:$git) = -1,
  Bool :q(:$quiet) = False,
  Str :f(:$filter) = '',
  :w(:@watch) = [],
) {

  my overwatch $overwatch;

  USAGE if @args.elems == 0;
  exit 0 if @args.elems == 0;

  $overwatch .=new(
    :$execute,
    :$keep-alive,
    :$exit-on-error,
    :$git,
    :$quiet,
    :$filter,
    :@watch
  );


  if !$quiet {
    $overwatch.events.tap(-> $event {
      given $event<action> {
        when 'start' {
          '[INFO] Starting overseer with options:'.say;
          "[INFO]   --execute: {$event<execute>}".say;
          "[INFO]   --restart: {$event<execute>}".say;
          "[INFO]   --filters: {$event<filters>.join(', ')}".say;
          "[INFO]     --watch: {$event<watch>.join(', ')}".say;
          "[INFO]       --git: {$event<git-interval> <= 0 ?? 'disabled' !! "{$event<git-interval>}m"}".say;
          "[INFO]      script: {$event<args>.map({ "'$_'" }).join(' ')}".say;
        }
        when 'error' {
          "[ERROR] {$event<msg>}".say;
        }
        when 'file-changed' {
          "[ERROR] Restarting process, file changed: {$event<file-path>}".say;
        }
        when 'git-pull' {
          '[INFO] Pulling from remote repository'.say;
        }
        when 'kill-proc' {
          "[INFO] Killing process with {$event<signal>}".say;
        }
        when 'proc-died' {
          "[INFO] Exit code ({$event<code>}) caught, exiting".say;
        }
        when 'restart' {
          "[INFO] Restarting {$event<execute>}".say;
        }
      }
    });
  }

  $overwatch.go(@args);
}

sub USAGE {
  my $space = ' ' x 4;
  say qq|Perl6 Overwatch can be used to restart programs when they crash or 
when files are modified.  

Usage: 
{$space}overwatch [options] <program> [<program arguments>]
    
Required:
{$space}<program>
{$space x 2}A program/script name is required.

Options:
{$space}-e=<executable> \| --execute=<executable>
{$space x 2}Default: 'perl6'
{$space x 2}The executable that runs the specified <program>.

{$space}-k \| --keep-alive
{$space x 2}Default: True
{$space x 2}Automatically rerun the program.
 
{$space}-x \| --exit-on-error
{$space x 2}Default: False
{$space x 2}Stop overwatch if the <program> exited with a
{$space x 2}non-zero code.

{$space}-g \| --git
{$space x 2}Default: 0
{$space x 2}Checks default upstream git repository and pulls
{$space x 2}if local is behind. 
{$space x 2}A value of zero or less disables this option.

{$space}-q \| --quiet
{$space x 2}Default: False
{$space x 2}Prevents overwatch from printing informative
{$space x 2}messages to stdout. 

{$space}-w \| --watch
{$space x 2}Default: []
{$space x 2}Directories/files to watch for changes, when a
{$space x 2}file is changed the <program> is restarted.

{$space}-f \| --filter
{$space x 2}Default: ''
{$space x 2}Comma separated list of file extensions to watch
{$space x 2}for changes.  List applies to all --watch dirs.

Notes:
{$space}Multiple -w switches may be specified
{$space}To negate a [True\|False} value you can use -/q (same as -q=False)

Examples:
{$space}overwatch app.pl6
{$space}overwatch -w=models mvc.pl6
{$space}overwatch -w=/tmp/ -e=/bin/sh shellscript.sh --shellarg=go
|

}
