package App::Clifton::ConsoleService;

use Log::Contextual qw(:log);
use aliased 'App::Clifton::ConsoleService::Session';
use IO::Async::Listener;
use IO::Socket::UNIX;
use Moo;

extends 'App::Clifton::Service';

has socket_location => (is => 'ro', default => sub { 'clifton.sock' });

has $_ => (is => 'lazy') for qw(listener session socket);

has server => (is => 'ro', required => 1, weak_ref => 1);

sub _build_socket {
  my ($self) = @_;
  my $location = $self->socket_location;
  unlink($location) if -e $location;
  IO::Socket::UNIX->new(
    Local => $location,
    Listen => 1,
  ) or die "Cannot make UNIX socket - $!\n";
}

sub _build_listener {
  my ($self) = @_;
  $self->_new_child('IO::Async::Listener', {
    on_stream => $self->_replace_weakself('_open_connection'),
    handle => $self->socket,
  });
}

sub _build_session {
  my ($self) = @_;
  Session->new->${\sub {
    my ($session) = @_;
    # no need to weaken this since server is already weak
    $session->lex_env->lexicals->{'$_SERVER'} = \$self->server;
    $session;
  }};
}

sub BUILD {
  my ($self) = @_;
  $self->$_ for qw(listener session);
}

sub _open_connection {
  my ($self, $stream) = @_;
  log_debug { "Connection opened" };
  $self->session->configure(transport => $stream);
  $self->add_child($self->session);
}

1;
