#/*
# *  Copyright 2007 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: log.pm 640 2007-05-13 14:02:43Z hikarin $
#

package Zeromin2::App::log;

use strict;

sub load_error {
    my ($zApp) = @_;
    $zApp->privilege('can_view_error_log')
        or return $zApp->return_value( 1, [] );

    my $iRequest = $zApp->request();
    my $type     = $iRequest->param('type');
    my ( $content, $year, $month, $day, $page );
    my $date = $iRequest->param('date') || '';
    if ( $date =~ m{\A(\d{4})[/\-](\d{2})[/\-](\d{2})\z}xms ) {
        ( $year, $month, $day ) = (
            Img0ch::Kernel::intval($1),
            Img0ch::Kernel::intval($2),
            Img0ch::Kernel::intval($3)
        );
    }
    else {
        my ( undef, undef, undef, $current_day, $current_month,
            $current_year )
            = localtime( time() );
        $current_year  += 1900;
        $current_month += 1;
        $year  = $iRequest->param_int('year')  || $current_year;
        $month = $iRequest->param_int('month') || $current_month;
        $day   = $iRequest->param_int('day')   || $current_day;
    }

    require Zeromin::Log::Error;
    my $zLogErr = Zeromin::Log::Error->new( $zApp->bbs() || $zApp->kernel() );
    my $by      = $iRequest->param('by');
    my $key     = $iRequest->param('key');
    $zLogErr->load();

    if ( $by eq 'all' ) {

        # Img0ch::BBS => bbs_dir | Img0ch::Kernel => undef
        ( $content, $page )
            = $zLogErr->all_in_with_page( undef, $key, $zApp->page_param() );
    }
    elsif ( $by eq 'month' ) {

        # Img0ch::BBS => bbs_dir | Img0ch::Kernel => undef
        ( $content, $page )
            = $zLogErr->retrive_by_month_in_with_page( $year, $month, undef,
            $key, $zApp->page_param() );
    }
    else {

        # Img0ch::BBS => bbs_dir | Img0ch::Kernel => undef
        ( $content, $page )
            = $zLogErr->retrive_by_day_in_with_page( $year, $month, $day,
            undef, $key, $zApp->page_param() );
    }

    _format_date( $content, 'date' );
    $zApp->add_template_param( { By => $by, Date => $date } );
    return $zApp->return_value( 0, $content, $page );
}

sub download_error {
    my ($zApp) = @_;
    $zApp->prevent_saving_session();
    $zApp->privilege('can_view_error_log')
        or return $zApp->return_value( 1, [] );

    $zApp->content_type('text/x-csv');
    $zApp->request()
        ->set_header( 'content-disposition',
        'attachment; filename="' . _filename('error') . '"' );
    return load_error($zApp);
}

sub load_user {
    my ($zApp) = @_;
    $zApp->privilege('can_enter_log_section')
        or return $zApp->return_value( 1, [] );

    my $iRequest = $zApp->request();
    my $type     = $iRequest->param('type');
    my ( $content, $year, $month, $day, $page );
    my $date = $iRequest->param('date') || '';
    if ( $date =~ m{\A(\d{4})[/\-](\d{2})[/\-](\d{2})\z}xms ) {
        ( $year, $month, $day ) = (
            Img0ch::Kernel::intval($1),
            Img0ch::Kernel::intval($2),
            Img0ch::Kernel::intval($3)
        );
    }
    else {
        my ( undef, undef, undef, $current_day, $current_month,
            $current_year )
            = localtime( time() );
        $current_year  += 1900;
        $current_month += 1;
        $year  = $iRequest->param_int('year')  || $current_year;
        $month = $iRequest->param_int('month') || $current_month;
        $day   = $iRequest->param_int('day')   || $current_day;
    }

    require Zeromin::Log::Action;
    my $zUser   = $zApp->user();
    my $zLogAct = Zeromin::Log::Action->new( $zApp->kernel() );
    my $by      = $iRequest->param('by');

    if ( $by eq 'all' ) {
        ( $content, $page )
            = $zLogAct->all_with_page( $zUser, '', $zApp->page_param() );
    }
    elsif ( $by eq 'month' ) {
        ( $content, $page )
            = $zLogAct->retrive_by_month_with_page( $year, $month, $zUser,
            $zApp->page_param() );
    }
    else {
        ( $content, $page )
            = $zLogAct->retrive_by_day_with_page( $year, $month, $day, $zUser,
            $zApp->page_param() );
    }

    _format_date( $content, 'date' );
    $zApp->add_template_param( { By => $by, Date => $date } );
    return $zApp->return_value( 0, $content, $page );
}

sub download_user {
    my ($zApp) = @_;
    $zApp->prevent_saving_session();
    $zApp->privilege('can_enter_log_section')
        or return $zApp->return_value( 1, [] );

    $zApp->content_type('text/x-csv');
    $zApp->request()
        ->set_header( 'content-disposition',
        'attachment; filename="' . _filename('user') . '"' );
    return load_user($zApp);
}

sub load_thread {
    my ($zApp) = @_;
    $zApp->privilege( 'can_view_thread_log', 1 )
        or return $zApp->return_value( 1, [] );

    if ( my $iBBS = $zApp->bbs() ) {
        require Zeromin::Log::Thread;
        my $zLogThr = Zeromin::Log::Thread->new($iBBS);
        $zLogThr->load();
        my ( $content, $page )
            = $zLogThr->all_with_page( $zApp->page_param() );
        _format_date( $content, 'atime' );
        return $zApp->return_value( 0, $content, $page );
    }
    return $zApp->return_value(1);
}

sub download_thread {
    my ($zApp) = @_;
    $zApp->prevent_saving_session();
    $zApp->privilege('can_view_thread_log')
        or return $zApp->return_value( 1, [] );

    $zApp->content_type('text/csv');
    $zApp->request()
        ->set_header( 'content-disposition',
        'attachment; filename="' . _filename('thread') . '"' );
    return load_thread($zApp);
}

sub lookup {
    my ($zApp) = @_;
           $zApp->privilege('can_view_thread_log')
        or $zApp->privilege('can_view_error_log')
        or $zApp->privilege('can_enter_log_section')
        or return $zApp->return_value(1);

    my $ip = $zApp->request()->param('ip');
    if ( $ip !~ /\A(\d+)\.(\d+)\.(\d+)\.(\d+)\z/xms ) {
        $zApp->add_template_param(
            {   Country  => '**',
                Listed   => [],
                Resolved => '(null)'
            }
        );
        return $zApp->return_value(2);
    }
    my @ipaddr = ( $1, $2, $3, $4 );

    require Img0ch::Plugin::Module::RACC;
    my $cc = eval {
        return Img0ch::Plugin::Module::RACC->get( $ip,
            $zApp->kernel()->get_config() );
    } || '--';

    my %dnsbl = (
        'niku.2ch.net'  => '%d.%d.%d.%d.niku.2ch.net',
        'bbx.2ch.net'   => '%d.%d.%d.%d.bbx.2ch.net',
        'list.dsbl.org' => '%d.%d.%d.%d.list.dsbl.org',
        'all.rbl.jp'    => '%d.%d.%d.%d.all.rbl.jp',

        #        'bl.spamcop.net'       => '%d.%d.%d.%d.bl.spamcop.net',
        #        'sbl-xbl.spamhaus.org' => '%d.%d.%d.%d.sbl-xbl.spamhaus.org',
        #        'opm.blized.org'       => '%d.%d.%d.%d.opm.blitzed.org',
        #        'bsb.empty.us'         => '%d.%d.%d.%d.bsb.empty.us',
        #        'bsb.spamlookup.net'   => '%d.%d.%d.%d.bsb.spamlookup.net',
    );
    my $ret = {};
    my $host = gethostbyaddr( pack( 'C*', @ipaddr ), 2 ) || $ip;
    for my $dnsbl_name ( sort keys %dnsbl ) {
        my $dnsbl_addr = $dnsbl{$dnsbl_name};
        my $addr = sprintf $dnsbl_addr, reverse(@ipaddr);
        $ret->{$dnsbl_name} = gethostbyname($addr) ? 1 : 0;
    }

    my $stack = [];
    map { push @$stack, { $_ => $ret->{$_} } } keys %$ret;

    $zApp->add_template_param(
        {   Country  => $cc,
            Listed   => $stack,
            Resolved => $host
        }
    );
    return $zApp->return_value( 0,
        { resolved => $host, country => $cc, listed => $ret } );
}

sub _filename {
    my ($prefix) = @_;
    my ( undef, undef, undef, $current_day, $current_month, $current_year )
        = localtime( time() );
    $current_year  += 1900;
    $current_month += 1;
    return sprintf '%04d-%02d-%02d-%s.csv', $current_year, $current_month,
        $current_day, $prefix;
}

sub _format_date {
    my ( $content, $key ) = @_;
    require Zeromin2::Util;
    map { $_->{$key} = Zeromin2::Util::format_date( $_->{$key} ) } @$content;
    return;
}

1;
__END__
