#!/usr/bin/env perl
# This is a simple script that connects stdin/stdout with a client
# connection to an irc server. the command line arguments are:
#
# $ ./debug_console <nick> <server> <port>
#
use common::sense;
use IO::Handle;
use AnyEvent;
use AnyEvent::IRC::Client;
use AnyEvent::IRC::Util qw/mk_msg parse_irc_msg encode_ctcp/;
use AnyEvent::Redis;
use Data::Dump qw(dump);
use Carp qw(confess);

my $nick = $ENV{IRC_NICK} || die "IRC_NICK";
my $room = $ENV{IRC_ROOM} || die "IRC_ROOM";
my $subscribe  = $ENV{IRC_SUBSCRIBE} || die 'IRC_SUBSCRIBE';

my $c = AnyEvent->condvar;
my $stdout = AnyEvent::Handle->new (fh => \*STDOUT);
my $con = new AnyEvent::IRC::Client;

my $sub = AnyEvent::Redis->new( host => $ENV{REDIS_HOST}, port => $ENV{REDIS_PORT}, on_error => sub { confess @_ } );

warn "# server:$ENV{IRC_SERVER}:$ENV{IRC_PORT} room:$room nick:$nick subscribe:$subscribe\n";

$sub->psubscribe( "MSG $subscribe", sub {
	my ( $message, $from ) = @_;
	return unless $from !~ m/\Q($nick|$room)\E/; # FIXME: skip our messages
	warn "#Q<< ",dump( $from, $message );
	my ( undef, $channel, $user ) = split(/ /,$from,3);
	$con->send_msg( 'PRIVMSG', $room => join(' ',$channel, $user, $message) );
});

$con->reg_cb (
   connect => sub {
      my ($con, $err) = @_;

      if (defined $err) {
         warn "Couldn't connect: $err\n";
         $c->broadcast;
      } else {
         $stdout->push_write ("Connected!\n");
      }

      $con->register ($nick, $nick, $nick);
   },
   debug_recv => sub {
      my ($con, $msg) = @_;
      $stdout->push_write (
         "< "
         . mk_msg ($msg->{prefix}, $msg->{command}, @{$msg->{params}})
         . "\n"
      );

		if ( $msg->{command} eq 'PRIVMSG' ) {
			my ( $to, $body ) = @{ $msg->{params} };
			my $channel = join(' ', 'MSG', "$nick/$to", $msg->{prefix});
			warn "#Q>> $channel | $body\n";
			my $pub = AnyEvent::Redis->new( host => $ENV{REDIS_HOST}, port => $ENV{REDIS_PORT}, on_error => sub { confess @_ } );
			$pub->publish( $channel, $body );
		} elsif ( $msg->{command} eq 'MODE' ) {
			$con->send_srv( JOIN => $room );
		}
   },
   debug_send => sub {
      my ($con, @msg) = @_;
      $stdout->push_write (
         "> " . mk_msg (undef, @msg) . "\n"
      );
warn dump(@msg);
   },
   registered => sub {
      my ($con) = @_;

      my $stdin;
      $stdin = AnyEvent::Handle->new (
         fh => \*STDIN,
         on_eof => sub {
            warn "EOF on STDIN, disconnecting...\n";
            $con->disconnect ("Console EOF");
         },
         on_error => sub {
            warn "Error on STDIN: $!\n";
         },
         on_read => sub {
            $stdin->push_read (line => sub {
               my ($stdin, $line) = @_;

               if ($line =~ /^!/) {
                  my $r = eval $line;
                  if ($@) {
                     warn "eval error: $@\n";
                  } else {
                     $Data::Dumper::Terse = 1;
                     $stdout->push_write ("result: " . dump($r));
                  }
               } else {
                  my $msg = parse_irc_msg ($line);
                  $con->send_msg ($msg->{command}, @{$msg->{params}});
               }
            });
         }
      );
   },
   disconnect => sub {
      warn "disconnect: $_[1]!\n";
      $c->broadcast
   },
);

$con->ctcp_auto_reply('VERSION', ['VERSION', 'MQR-IRC:0.1:Perl']);

$con->connect ($ENV{IRC_SERVER}, $ENV{IRC_PORT} || 6667);

$c->wait;
