package App::Clifton::Tower::IRC;

use aliased 'Net::Async::IRC' => 'IRC_Client';
use aliased 'App::Clifton::Chain';
use Log::Contextual qw(:log);
use Moo;
             
extends 'App::Clifton::Component';

has server => (is => 'ro', required => 1, weak_ref => 1);
has irc_server => (is => 'ro', required => 1);
has irc_nick => (is => 'ro', required => 1);
has irc_client => (is => 'lazy');
has chains => (is => 'ro', default => sub { {} });

sub _build_irc_client { shift->_new_child(IRC_Client, {}) }

sub BUILD {
  my ($self, $args) = @_;
  my $on_setup = $args->{on_setup};
  $self->irc_client->configure(
    on_message_text => $self->_replace_weakself('receive_irc_message'),
    on_message_ctcp_ACTION => $self->_replace_weakself('receive_irc_message')
  );
  $self->irc_client->login(
    nick => $self->irc_nick, host => $self->irc_server,
    on_login => $self->_capture_weakself(sub {
      my $self = shift;
      $self->server->irc_towers->{$self->irc_server}{$self->irc_nick}
        = $self;
      $on_setup->($self);
    }),
  );
}

sub start_chain {
  my ($self, $args) = @_;
  $self->irc_client->send_message('JOIN', undef, $args->{irc_channel});
  my $new = $self->_new_child(Chain, {
    %$args, irc_tower => $self,
  });
  $self->chains->{$args->{irc_channel}} = $new;
  # I note here that actually we should make the Chain do
  # setup (JOIN) and confirm that first, but oh well
  $args->{on_finished}->({
    chain => $new,
    message => 'SUCCESS'
  });
}

sub stop_chain {
  my ($self, $chain) = @_;
  $self->irc_client->send_message('PART', undef, $chain->irc_channel);
  delete $self->chains->{$chain->irc_channel};
  $self->remove_child($chain);
}

sub send_irc_message {
  my ($self, $args) = @_;
  $self->irc_client->send_message('PRIVMSG', undef, @{$args}{qw(to text)});
}

sub receive_irc_message {
  my ($self, $message, $hints) = @_;
  return if $hints->{prefix_is_me};
  if (my $chain = $self->chains->{$hints->{target_name}||''}) {
    $chain->handle_irc_message($message, $hints);
  } elsif ($chain = $self->chains->{$hints->{targets}||''}) {
    $chain->handle_irc_message($message, $hints);
  }
}

1;
