#!/usr/bin/env raku

use v6.d;
use MVC::Keayl::CLI;

my $NAME = program-name();

multi sub MAIN('version') { say framework-version(); }
multi sub MAIN('help')    { say usage(); }

multi sub MAIN('new', $name) {
  my @created = scaffold-app($name);
  say "created $name/$_" for @created;
  exit 0;
}

multi sub MAIN('server', Str :$host = '127.0.0.1', Int :$port = 3000) { exit serve(:$host, :$port); }
multi sub MAIN('s',      Str :$host = '127.0.0.1', Int :$port = 3000) { exit serve(:$host, :$port); }

sub serve(Str:D :$host, Int:D :$port --> Int) {
  my $app = load-application();
  return 1 unless $app.defined;

  my $adapter = build-server($app, :$host, :$port);
  $adapter.start;

  say "$NAME: listening on http://$host:$port ($app.environment())";

  react { whenever signal(SIGINT) { $adapter.stop; done } }

  0
}

multi sub MAIN('routes') { exit print-routes(); }

multi sub MAIN('console') { exit console(); }
multi sub MAIN('c')       { exit console(); }

multi sub MAIN('generate', $type, $name, *@actions) { exit generate($type, $name, @actions); }
multi sub MAIN('g',        $type, $name, *@actions) { exit generate($type, $name, @actions); }

sub generate(Str:D $type, Str:D $name, @rest --> Int) {
  given $type {
    when 'controller' { generate-controller($name, @rest) }
    when 'scaffold'   { generate-scaffold($name) }
    when 'mailer'     { generate-mailer($name, @rest) }
    when 'job'        { generate-job($name) }
    when 'channel'    { generate-channel($name) }
    when 'helper'     { generate-helper($name) }
    when 'model'      { generate-model($name, @rest) }
    when 'migration'  { generate-migration($name, @rest) }
    when 'resource'   { generate-resource($name, @rest) }
    default {
      note "$NAME: unknown generator '$type' (expected: controller, scaffold, mailer, job, channel, helper, model, migration, resource)";
      2;
    }
  }
}

multi sub MAIN('credentials-edit', Str :$env) { exit credentials-edit(:$env); }

multi sub MAIN('assets-precompile') { exit assets-precompile(); }

multi sub MAIN(Bool :$version) {
  if $version {
    say framework-version();
  } else {
    say usage();
  }
}
