# Copyright (c) 2025 Yuki Kimoto
# MIT License

class Mojolicious::Command::Hypnotoad extends Mojolicious::Command {
  version_from Mojolicious;
  
  use Mojo::Server::Hypnotoad;
  use Mojo::Util;
  use Fn;
  
  # Class Methods
  static method new : Mojolicious::Command::Hypnotoad () {
    
    my $self = new Mojolicious::Command::Hypnotoad;
    
    $self->init;
    
    return $self;
  }
  
  # Instance Methods
  protected method init : void () {
    
    $self->SUPER::init;
    
    $self->{description} = "Hypnotoad HTTP and WebSocket server";
    
    $self->{usage} = <<'EOS';
Usage: hypnotoad [OPTIONS] [APPLICATION]

  ./myapp.spvm hypnotoad
  ./myapp.spvm hypnotoad -f

Options:
  -f, --foreground   Keep manager process in foreground
  -h, --help         Show this message
  -s, --stop         Stop server gracefully
  -t, --test         Test application and exit

EOS
  }
  
  method build_server : Mojo::Server::Hypnotoad ($args : string[] = undef) {
    
    my $values_h = Hash->new;
    
    my $specs = [
      "f|foreground",
      "h|help",
      "s|stop",
      "t|test",
    ];
    
    eval { Mojo::Util->getopt(my $_ = [$args], $values_h, $specs); }
    
    if ($@) {
      die $self->usage;
    }
    
    if ($values_h->{"help"}->(int)) {
      print $self->usage;
      Sys->exit(0);
    }
    
    if ($values_h->exists("foreground")) {
      my $foreground = $values_h->{"foreground"}->(int);
      Sys->set_env("SPVM_HYPNOTOAD_FOREGROUND", $foreground);
    }
    
    if ($values_h->exists("stop")) {
      my $stop = $values_h->{"stop"}->(int);
      Sys->set_env("SPVM_HYPNOTOAD_STOP", $stop);
    }
    
    if ($values_h->exists("test")) {
      my $test = $values_h->{"test"}->(int);
      Sys->set_env("SPVM_HYPNOTOAD_TEST", $test);
    }
    
    my $server = Mojo::Server::Hypnotoad->new;
    
    my $app = $self->app;
    
    $server->set_app($app);
    
    return $server;
  }
  
  method run : void ($args : string[]) {
    
    $self->build_server($args)->run;
  }
  
}