#/*
# *  Copyright 2007-2010 hkrn <hikarin@users.sourceforge.jp>
# *
# *  Licensed under the Apache License, Version 2.0 (the "License");
# *  you may not use this file except in compliance with the License.
# *  You may obtain a copy of the License at
# *
# *      http://www.apache.org/licenses/LICENSE-2.0
# *
# *  Unless required by applicable law or agreed to in writing, software
# *  distributed under the License is distributed on an "AS IS" BASIS,
# *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# *  See the License for the specific language governing permissions and
# *  limitations under the License.
# */
#
# $Id: IP.pm 1957 2010-01-23 11:18:01Z hikarin $
#

package Zeromin::Filter::IP;

use strict;
use base qw(Img0ch::Filter::IP);

sub new {
    my ( $zClass, $iObject ) = @_;
    my $class = ref $iObject || '';
    my $zFIP;

    if ( $class eq 'Img0ch::BBS' ) {
        $zFIP             = $zClass->SUPER::new($iObject);
        $zFIP->{__bbs_id} = $iObject->get_id();
        $zFIP->{__kernel} = $iObject->get_kernel();
    }
    elsif ( $class eq 'Img0ch::Kernel' or $class eq 'Img0ch::Maple' ) {
        require Img0ch::BBS;
        my $iBBS = Img0ch::BBS->new( $iObject, { id => 0 } );
        $zFIP             = $zClass->SUPER::new($iBBS);
        $zFIP->{__bbs_id} = 0;
        $zFIP->{__kernel} = $iObject;
    }
    else {
        Img0ch::Kernel->throw_exception(
            'Img0ch::BBS or Img0ch::Maple not given');
    }

    $zFIP->{__buffer} = [];
    return $zFIP;
}

sub load {1}

sub save {
    my ($zFIP) = @_;
    my $iRepos = $zFIP->{_rs};
    my $bbs    = $zFIP->{_bbs};
    my $buffer = $zFIP->{__buffer};

    for my $one (@$buffer) {
        my ( $i1, $i2, $i3, $i4 )
            = ( $one->[1], $one->[2], $one->[3], $one->[4] );
        $iRepos->set( "I:F:I.${bbs}.${i1}.${i2}.${i3}.${i4}", 1 );
    }

    @{ $zFIP->{__buffer} } = ();
    $iRepos->save();
    return 1;
}

sub get {
    my ( $zFIP, $ip ) = @_;
    my @addr   = split '\.', $ip;
    my $iRepos = $zFIP->{_rs};
    my $bbs    = $zFIP->{_bbs};
    my ( $i1, $i2, $i3, $i4 ) = map { Img0ch::Kernel::intval($_) } @addr;

    if ( $iRepos->get("I:F:I.${bbs}.${i1}.${i2}.${i3}.${i4}") ) {
        return {
            bbs => $zFIP->{__bbs_id},
            ip  => $ip,
            ip1 => $i1,
            ip2 => $i2,
            ip3 => $i3,
            ip4 => $i4,
        };
    }
    if ( $iRepos->get("I:F:I.test.${i1}.${i2}.${i3}.${i4}") ) {
        return {
            bbs => 0,
            ip  => $ip,
            ip1 => $i1,
            ip2 => $i2,
            ip3 => $i3,
            ip4 => $i4,
        };
    }

    return {
        bbs => undef,
        ip  => undef,
        ip1 => 0,
        ip2 => 0,
        ip3 => 0,
        ip4 => 0
    };
}

sub all {
    my ($zFIP) = @_;
    my $ret = [];

    $zFIP->{_rs}->iterate(
        sub {
            my ( $key, $value, $iKernel, $stack ) = @_;
            $key =~ m/\AI:F:I\.(.+?)\.(\d+)\.(\d+)\.(\d+)\.(\d+)\z/xms;
            push @$stack,
                {
                bbs => Img0ch::BBS->new( $iKernel, { bbs => $1 } )->get_id(),
                ip  => join( '.', $2, $3, $4, $5 ),
                ip1 => $2,
                ip2 => $3,
                ip3 => $4,
                ip4 => $5,
                };
        },
        $zFIP->{__kernel},
        $ret
    );
    return $ret;
}

sub all_with_page {
    my ( $zFIP, $item_per_page, $offset ) = @_;

    defined $Data::Page::VERSION or require Data::Page;
    my $entries = $zFIP->all();
    my $page = Data::Page->new( scalar @$entries, $item_per_page, $offset );
    return ( [ $page->splice($entries) ], $page );
}

sub all_in {
    my ( $zFIP, $bbs ) = @_;
    my $data = $zFIP->all();
    $bbs ||= $zFIP->{__bbs_id};
    [ grep { $_->{bbs} == $bbs } grep { defined $_->{bbs} } @$data ];
}

sub all_in_with_page {
    my ( $zFIP, $bbs, $item_per_page, $offset ) = @_;

    defined $Data::Page::VERSION or require Data::Page;
    my $entries = $zFIP->all_in($bbs);
    my $page = Data::Page->new( scalar @$entries, $item_per_page, $offset );
    return ( [ $page->splice($entries) ], $page );
}

sub add {
    my ( $zFIP, $ip ) = @_;
    my $buffer = $zFIP->{__buffer};

    for my $one (@$buffer) {
        $one->[0] eq $ip and return 0;
    }

    my @addr = map { Img0ch::Kernel::intval($_) } split( '\.', $ip );
    push @$buffer, [ $ip, @addr ];
    return 1;
}

sub remove {
    my ( $zFIP, $ip ) = @_;
    my @addr   = split '\.', $ip;
    my $iRepos = $zFIP->{_rs};
    my $bbs    = $zFIP->{_bbs};

    my ( $i1, $i2, $i3, $i4 ) = map { Img0ch::Kernel::intval($_) } @addr;
    my $removed = $iRepos->remove("I:F:I.${bbs}.${i1}.${i2}.${i3}.${i4}");
    return $removed ? 1 : 0;
}

1;
__END__
