#!/usr/bin/perl
use warnings;
use strict;

use POE qw(
    Session
    Component::IRC
    Component::IKC::Server
    Component::IKC::Specifier
    );

sub msg (@) { print "[msg] ", "@_\n" }
sub err (@) { print "[err] ", "@_\n" }

msg 'loading configuration';
require YAML;
my $config_yaml = YAML::LoadFile('config.yaml');
my ($plugin) = grep {$_->{module} eq 'Publish::IRC'} @{ $config_yaml->{plugins} };
my $config = $plugin->{config};
 
msg 'creating daemon component';
POE::Component::IKC::Server->spawn(
    port => $config->{daemon_port},
    name => 'NotifyIRCBot',
);

msg 'creating irc component';
POE::Component::IRC->new('bot')
    or die "Couldn't create IRC POE session: $!";

msg 'creating kernel session';
POE::Session->create(
    inline_states => {
        _start           => \&bot_start,
        _stop            => \&bot_stop,
        irc_001          => \&bot_connected,
        irc_372          => \&bot_motd,
        irc_disconnected => \&bot_reconnect,
        irc_error        => \&bot_reconnect,
        irc_socketerr    => \&bot_reconnect,
        autoping         => \&bot_do_autoping,
        update           => \&update,
        _default         => $ENV{DEBUG} ? \&bot_default : sub { },
    }
);

msg 'starting the kernel';
POE::Kernel->run();
msg 'exiting';
exit 0;

sub bot_default
{
    my ( $event, $args ) = @_[ ARG0 .. $#_ ];
    err "unhandled $event";
    err "  - $_" foreach @$args;
    return 0;
}

sub update
{
    my ( $kernel, $heap, $msg ) = @_[ KERNEL, HEAP, ARG0 ];
    eval {
        $kernel->post( bot => notice => "#$_", $msg )
            foreach split /,\s+/, $config->{server_channels};
    };
    err "update error: $@" if $@;
}

sub bot_start
{
    my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
    msg "starting irc session";
    $kernel->alias_set('notify_irc');
    $kernel->call( IKC => publish => notify_irc => ['update'] );
    $kernel->post( bot => register => 'all' );
    $kernel->post(
        bot => connect => {
            Nick     => $config->{nickname},
            Ircname  => $config->{ircname},
            Username => $ENV{USER},
            Server   => $config->{server_host},
            Port     => $config->{server_port},
        }
    );
}

sub bot_stop
{
    msg "stopping bot";
}

sub bot_connected
{
    my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
    foreach ( split /,\s+/, $config->{server_channels} )
    {
        msg "joining channel #$_";
        $kernel->post( bot => join => "#$_" );
        $kernel->post( bot => charset => 'iso-2022-jp' );
    }
}

sub bot_motd
{
    msg '[motd] ' . $_[ARG1];
}

sub bot_do_autoping
{
    my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
    $kernel->post( bot => userhost => $config->{nickname} )
        unless $heap->{seen_traffic};
    $heap->{seen_traffic} = 0;
    $kernel->delay( autoping => 300 );
}

sub bot_reconnect
{
    my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
    err "reconnect: " . $_[ARG0];
    $kernel->delay( autoping => undef );
    $kernel->delay( connect  => 60 );
}


