#/*
# *  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 610 2007-05-09 14:49:15Z hikarin $
#

package Img0ch::Compat::Log;

use strict;

sub load {
    my ($iBBS) = @_;

    require Time::Local;
    require Img0ch::Thread;
    my $iKernel = $iBBS->get_kernel();
    my $iConfig = $iKernel->get_config();
    my $dir     = $iBBS->get_name();
    my $base    = join '/', $iConfig->get('BBSPath'), $dir;
    my $path    = join '/', $base, 'log/HOSTs.cgi';
    -r $path or return 0;

    my $idx    = {};
    my $thread = {};
    my $log    = {};
    my $datdir = join '/', $base, $dir, 'dat';
    _build_temporary_index( $iKernel, $datdir, $idx );

    local ( $!, *FH );
    local $SIG{__WARN__} = sub { };
    open *FH, "<${path}" or    ## no critic
        $iKernel->throw_io_exception($path);
    while ( my $line = <FH> ) {
        chomp $line;
        my ( $time, $key, undef, $host ) = split '<>', $line;
        my $resno = $idx->{ ( join '-', $key, $time ) } || next;

        my $iLog = $log->{$key};
        if ($iLog) {
            $iLog = Img0ch::Log->new( $iBBS, $key );
            $iLog->load();
            $log->{$key} = $iLog;
        }
        my $iThread = $thread->{$key};
        if ( !$iThread ) {
            $iThread = Img0ch::Thread->new( $iBBS, $key );
            $iThread->load();
            $thread->{$key} = $iThread;
        }

        my $article = $iThread->get($resno);
        if ($article) {
            my $ip;
            if ( $host =~ /\A(\d+)\.(\d+)\.(\d+)\.(\d+)\z/xms ) {
                $ip = "$1.$2.$3.$4";
            }
            else {
                $ip = join '.', unpack( 'C*', gethostbyname $host );
            }
            $host =~ /\s([\w\-]+)\z/xms;
            my $serial = $1 || '';
            $iLog->set( $resno, [ $time, $ip, $serial, '' ] );
        }
    }
    close *FH or $iKernel->throw_io_exception($path);
    map { $_->save() } values %$log;
    return 1;
}

sub _build_temporary_index {
    my ( $iKernel, $datdir, $index ) = @_;

    local ( $!, *DH );
    opendir *DH, $datdir or $iKernel->throw_io_exception($datdir);
    my @datfiles = readdir *DH;
    closedir *DH or $iKernel->throw_io_exception($datdir);

DAT_SCAN:
    for my $datfile (@datfiles) {
        $datfile =~ /\A(\d{9,10})\.dat\z/xms or next DAT_SCAN;
        my $key     = $1;
        my $datpath = join '/', $datdir, $datfile;
        my $i       = 0;
        local ( $!, *FH );

        open *FH, "<${datpath}"    ## no critic
            or $iKernel->throw_io_exception($datpath);
    DAT_READ:
        while ( my $line = <FH> ) {
            $i++;
            $line =~ /\A.*?<>.*?<>(.*?)<>.*?<>.*\z/xms or next DAT_READ;
            my $date = $1;
            $date =~ /.*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+)/xms
                or next DAT_READ;
            my ( $year, $month, $day, $hour, $minute, $second )
                = map { Img0ch::Kernel::intval($_) }
                ( $1, $2, $3, $4, $5, $6 );
            my $stamp = Time::Local::timelocal( $second, $minute, $hour, $day,
                $month - 1, $year - 1900 );
            $index->{ ( join '-', $key, $stamp ) } = $i;
        }
        close *FH or $iKernel->throw_io_exception($datpath);
    }
    return;
}

1;
__END__
