package App::FonBot::Plugin::IRC;

our $VERSION = '0.000_1';

use v5.14;
use strict;
use warnings;

use Apache2::Authen::Passphrase qw/pwcheck/;
use IRC::Utils qw/parse_user/;
use Log::Log4perl qw//;
use POE;
use POE::Component::IRC qw//;

use Text::ParseWords qw/shellwords/;
use subs qw/shutdown/;

use App::FonBot::Plugin::Common;

##################################################

my %selves;

sub init{
  my ($ns)=@_;

  my $self=$ns->new;
  $self->{log}->info("initializing $ns");
  tie my %nick_to_username, DB_File => "nick_to_username-$ns.db";
  $self->{nick_to_username}=\%nick_to_username;
  $selves{$ns}=$self
}

sub fini{
  my ($ns)=@_;

  $selves{$ns}->{log}->info("finishing $ns");
  $selves{$ns}->{irc}->yield(shutdown => "finishing $ns") if defined $selves{$ns}->{irc};
  untie $selves{$ns}->{nick_to_username};
  POE::Kernel->post($selves{$ns}->{session} => 'shutdown');
  delete $selves{$ns}
}

##################################################

sub new{
  my ($ns)=@_;

  my $self = {
	prefix => {},
	log => Log::Log4perl->get_logger($ns),
  };

  bless $self, $ns;

  $self->{session} = POE::Session->create(
	object_states => [ $self => [ '_start', 'send_message', 'irc_001', 'irc_msg', 'irc_public', 'shutdown' ] ],
  );

  $self
}

sub irc_msg{
  my ($from, $msg, $self)=@_[ARG0,ARG2,OBJECT];
  my $nick=parse_user $from;

  my $username=$self->{nick_to_username}{$from};
  my $address=$_[KERNEL]->alias_list;
  $address.=" $nick";

  chomp $msg;
  my @args=shellwords $msg;
  my $cmd=shift @args;

  given($cmd){
	when(/^myid$/i){
	  $self->{irc}->yield(privmsg => $nick, $from);
	}

    when(/^login$/i) {
	  my ($user, $pass) = @args;

	  eval { pwcheck $user, $pass };

	  if ($@) {
		$self->{log}->debug("Login for $user failed");
		$self->{irc}->yield(privmsg => $nick, 'Bad username/password combination');
	  } else {
		$self->{log}->debug("Login for $user succeded");
		$self->{nick_to_username}{$from} = $user;
		$self->{irc}->yield(privmsg => $nick, "Logged in as $user");
	  }
    }

	when(/^logout$/i){
	  delete $self->{nick_to_username}{$from};
	}

    when(/^prefix$/i){
	  if (defined $username) {
		$self->{prefix}{$username} = [@args];
	  } else {
		$self->{irc}->yield(privmsg => $nick, 'You are not logged in. Say "login your_username your_password" (where your_username and your_password are your login credentials) to login.');
	  }
    }

    when(/^noprefix$/i){
	  if (defined $username) {
		delete $self->{prefix}{$username}
	  } else {
		$self->{irc}->yield(privmsg => $nick, 'You are not logged in. Say "login your_username your_password" (where your_username and your_password are your login credentials) to login.');
	  }
    }

	default {
	  if (defined $username) {
		$ok_user_addresses{"$username $address"}=1;
		$self->{log}->debug("Command $cmd @args from $username");
		if (exists $self->{prefix}{$username}) {
		  sendmsg $username, undef, $address, @{$self->{prefix}{$username}}, $cmd, @args;
		} else {
		  sendmsg $username, undef, $address, $cmd, @args;
		}
	  } else {
		$self->{irc}->yield(privmsg => $nick, 'You are not logged in. Say "login your_username your_password" (where your_username and your_password are your login credentials) to login.');
	  }
	}

  }
}

sub irc_public{
  # Do nothing
}

sub irc_001{
  # Do nothing
}

sub send_message{
  my ($self, $address, $content)=@_[OBJECT, ARG0, ARG1];
  $self->{irc}->yield(privmsg => $address, $_) for map {unpack '(A400)*'} split "\n", $content
}

sub shutdown{
  $_[KERNEL]->alias_remove($_) for $_[KERNEL]->alias_list;
}

sub _start { ... }

1
