#!/usr/bin/env perl
# pika-bot!
# Interfaces with LP for administrative work and scheduling of random tasks
#
# Author: Adam Stokes <adam.stokes@ubuntu.com>
# LGPLv2+

use strict;
use warnings;
use Net::OAuth::LP;
use Net::OAuth::LP::Client;
use POSIX;
use Try::Tiny;
use Date::Parse;
use YAML qw[LoadFile];
use File::Spec::Functions;

# use AnyEvent; # At some point
use POE qw(Component::IRC::State);
use Data::Dumper;
use Carp;

# Verify bot is authorized
my $cfg = (
    sub {
        my $cfg_file = catfile($ENV{HOME}, '.lp-auth.yml');
        try { LoadFile $cfg_file; }
        catch {
            carp("No LP Auth file, will need to re-authenticate.");
            my $lp = Net::OAuth::LP->new;
            $lp->consumer_key('seg-pika-bot');
            $lp->login_with_creds;
        }
    }
)->();

# Make sure we have a bot config for user access/roles
my $botcfg = (
    sub {
        my $bot_conf = catfile($ENV{HOME}, '.pika-bot.yml');
        try { LoadFile $bot_conf; }
        catch {
            croak(
                "No bot config found, make sure youve got a ~/.pika-bot.yml file."
            );
        }
    }
)->();

# We're authenticated *hopefully*
# Setup LP client
my $lpc =
  Net::OAuth::LP::Client->new($cfg->{consumer_key}, $cfg->{access_token},
    $cfg->{access_token_secret});

my $nickname = 'pika';
my $server   = 'localhost';
my $port     = 6969;

my @channels = ('#seg-team, #pika-test');

# We create a new PoCo-IRC object
my $irc = POE::Component::IRC::State->spawn(
    server   => $server,
    port     => $port,
    password => 'moo',
) or die "Oh noooo! $!";

POE::Session->create(
    package_states => [main => [qw(_start irc_001 irc_public)],],
    heap           => {irc  => $irc},
);

$poe_kernel->run();

sub _e {
    my ($nick, $where, $err) = @_;
    $irc->yield(privmsg => $where, "$nick: error ($err)");
}

sub _start {
    my ($kernel, $heap) = @_[KERNEL, HEAP];
    my $irc_session = $heap->{irc}->session_id();
    $kernel->post($irc_session => register => 'all');
    $kernel->post($irc_session => connect  => {});
    return;
}

sub irc_001 {
    my ($kernel, $sender) = @_[KERNEL, SENDER];

    # Since this is an irc_* event, we can get the component's object by
    # accessing the heap of the sender. Then we register and connect to the
    # specified server.
    my $irc = $sender->get_heap();

    print join(" ", "Connected to ", $irc->server_name(), "via pika-proxy\n");

    # we join our channels
    $kernel->post($sender => join => $_) for @channels;
    return;
}

sub irc_public {
    my ($kernel, $sender, $who, $where, $what) =
      @_[KERNEL, SENDER, ARG0 .. ARG2];
    my $nick    = (split /!/, $who)[0];
    my $channel = $where->[0];
    my $irc     = $sender->get_heap();

    # Public captures
    print Dumper($what);
    if (my ($bug_id) = $what =~ /^.*bug\s(\d+).*$/) {
        return _bug($irc, $bug_id, $nick, $where, $what);
    }

    if (my ($filter) = $what =~ /^!filter person::(.*)/) {
        return _who($irc, $filter, $nick, $where, $what);
    }
}

sub _bug {
    my ($irc, $bug_id, $nick, $where, $what) = @_;
    my ($bug, $err, $ret) =
      $lpc->bug('https://api.launchpad.net/1.0/bugs/' . $bug_id);
    unless ($ret < 1) {
        return _e($nick, $where, "Failed to query bug");
    }
    my $date =
      strftime("%m/%d/%Y %H:%M %P", strptime($bug->{date_last_message}));
    $irc->yield(
        privmsg => $where,
        join(" ",
            $nick . ':',  "[modified]", $date, "[heat]",
            $bug->{heat}, "[title]",   $bug->{title}, "[url] http://pad.lv/$bug_id")
    );
}


sub _who {
    my ($irc, $filter, $nick, $where, $what) = @_;

    my ($person, $err, $ret) = $lpc->me($filter);
    unless ($ret < 1) {
        return _e($nick, $where, "Failed to lookup $filter");
    }
    my ($bugs, $err, $ret) =
      $lpc->search('ubuntu-advantage', {'ws.op' => 'searchTasks',});

    my $cnt = 0;
    for my $line ($bugs->{entries}) {
        for my $line_in (@{$line}) {
            if (   $line_in->{assignee_link} eq $person->{self_link}
                && $line_in->{status} !~ m/Fix|Invalid|Incomplete|Opinion/)
            {
                $irc->yield(
                    privmsg => $where,
                    join(" ",
                        $nick,      ":",
                        "[status]", $line_in->{status},
                        "[imp]",    $line_in->{importance},
                        "[title]",  $line_in->{title})
                );
                $cnt++;
            }
            if ($cnt == 5) { return; }
        }
    }

}

1;
