package Xchat::VPIT::Opers;

use strict;
use warnings;

use Xchat qw<:all>;

use lib get_info 'xchatdir';
use Xchat::XPI;
use Xchat::XPI::Utils qw<irc_lc save_context>;

our $VERSION = '0.03';

my ($ph, %opers);

sub print_op { print $ph "\002$_[0]\002 ($_[1]) \002is an IRC operator\n" }

hook_server '352', sub {
 return EAT_NONE unless 0 <= rindex $_[0][8], '*';

 my $serv = get_info 'server';
 my $nick = $_[0][7];
 return EAT_NONE if $opers{$serv}{irc_lc($nick)};
 $opers{$serv}{irc_lc($nick)} = $nick;

 my $host = $_[0][4] . '@' . strip_code $_[0][5];
 my %chans;
 push @{$chans{$_->{type}}}, $_ for grep $_->{server} eq $serv,
                                     get_list 'channels';

 my $guard = save_context;

 my $onachan;
 for (@{$chans{2}}) {
  set_context $_->{context} or next;
  user_info   $nick         or next;
  print_op    $nick, $host;
  ++$onachan;
 }

 my @opchans;
 @opchans = @{$chans{1}} unless $onachan;
 push @opchans, grep !nickcmp($_->{channel}, $nick), @{$chans{3}};
 for (@opchans) {
  set_context $_->{context} or next;
  print_op $nick, $host;
 }

 return EAT_NONE;
};

hook_print 'Disconnected', sub {
 my %servers;
 $servers{$_->{server}} = 1 for grep +($_->{flags} & 0b1011) == 0b1001,
                                 get_list 'channels';

 delete @opers{grep !$servers{$_}, keys %opers};

 return EAT_NONE;
};

hook_server 'QUIT', sub {
 my ($nick) = $_[0][0] =~ /^:([^!]+)!/;

 my $serv = get_info 'server';
 delete $opers{$serv}{irc_lc($nick)};

 return EAT_NONE;
};

sub nick_cb {
 my ($old, $new) = @{$_[0]};

 $old = irc_lc $old;

 my $ops = $opers{get_info 'server'};
 if ($ops and $ops->{$old}) {
  $ops->{irc_lc($new)} = $new;
  delete $ops->{$old};
 }

 return EAT_NONE;
}

hook_print $_, \&nick_cb for 'Change Nick', 'Your Nick Changing';

hook_command 'OPSCAN', sub {
 my $serv = get_info 'server';
 if (!$opers{$serv}) {
  print $ph "No information for this network yet\n";
  return EAT_ALL;
 }

 my $chan  = get_info 'channel';
 my $isnet = 0;
 for (get_list 'channels') {
  if ($_->{type} == 1 and $_->{channel} eq $chan) {
   $isnet = 1;
   last;
  }
 }

 my ($name, @ops);
 if ($isnet) {
  $name = 'network';
  @ops  = values %{$opers{$serv}};
 } else {
  $name = 'channel';
  @ops  = map $_->{nick},
           grep $opers{$serv}{irc_lc($_->{nick})},
            get_list 'users';
 }

 if (@ops) {
  print $ph "IRC operators on this $name : \002@ops\n";
 } else {
  print $ph "No IRC operators on this $name\n";
 }

 return EAT_ALL;
}, {
 help_text => 'OPSCAN, scan for IRC operators in the current channel'
};

$ph = Xchat::XPI->new(
 name   => 'Operators',
 tag    => 'Opers',
 desc   => 'IRC operators scanner',
 author => 'Vincent Pit (VPIT)',
 email  => 'perl@profvince.com',
 url    => 'http://www.profvince.com',
 unload => sub { undef %opers },
);

1;
