use strict;
use warnings;
use Xchat qw(:all);

my $DEFAULT_TYPES = "ALL";

register(
	"Ignore with defaults",
	"1.0000",
);

my $mask_pattern = qr/^ [^!]+ ! [^\@]+ \@ .+ $/x;
hook_command( "IGNORE", sub {
	my (undef, $mask, @types) = @{$_[0]};

	# this is already the full version of the command, no need to do anything
	if( $mask =~ $mask_pattern and @types ) {
		return EAT_NONE;
	}

	push @types, $DEFAULT_TYPES unless @types;

	if( $mask !~ $mask_pattern ) {
		my $hook_id;
		$hook_id = hook_server(
			302,
			\&userhost_reply,
			{
				data => {
					hook_id => \$hook_id,
					nick => $mask,
					types => \@types,
				},
			}
		);
		command( "USERHOST $mask" );
	} else {
		command( "IGNORE $mask @types" );
	}

	return EAT_ALL;
});

sub userhost_reply {
	my $hook_data = $_[2];

	my $hook_id = ${$hook_data->{hook_id}};
	my $nick = $hook_data->{nick};
	my @types = @{$hook_data->{types}};
	
	(my $user_host = $_[0][3]) =~ s/^://;

	my ($user_nick, $user_name, $host) =
		$user_host =~ /^
			([^=]+) =     # nick
			[+-]          # away or not
			~?([^\@]+) \@ # user name
			(.+)          # host name
		/x;

	# don't do anything if this wasn't a reply to our USERHOST command
	return EAT_NONE if nickcmp( $nick, $user_nick );

	my @host_parts = split /[.]/, $host;
	my $host_mask;
	
	if( @host_parts > 2 ) {
		if( @host_parts == 4 and 4 == grep /^\d+$/, @host_parts ) {
			$host_mask = join ".", splice( @host_parts, 0, 3 ), "*";
		} else {
			$host_mask = join ".", "*", splice @host_parts, -2;
		}
	} else {
		$host_mask = join ".", @host_parts;
	}

	command( "IGNORE *!*$user_name\@$host_mask @types" );
	
	unhook( $hook_id );
	return EAT_ALL;

}
