#/*
# *  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: Collection.pm 1901 2009-12-31 02:40:20Z hikarin $
#

package Zeromin::Log::Collection;

use strict;
use File::Basename qw();
use File::Find qw();
use Time::Local qw();

sub new {
    my ( $iClass, $iKernel ) = @_;
    my $dir    = {};
    my $file   = {};
    my $regex1 = qr{
    /\w+/(\d{4})/(\d{1,2})/(\d{1,2})/(\d{9,10})/\w+\.\w+\z
    }xms;
    my $regex2 = qr{
    /(\d{4})/(\d{1,2})/(\d{1,2})/\w+\.\w+\z
    }xms;

    File::Find::find(
        {   bydepth  => 1,
            no_chdir => 1,
            untaint  => 1,
            wanted   => sub {
                my $name = $File::Find::name;
                if ( $name =~ $regex1 || $name =~ $regex2 ) {
                    my $ts
                        = $4
                        ? $4
                        : Time::Local::timelocal( 0, 0, 0, $3, $2 - 1,
                        $1 - 1900 );
                    $dir->{ File::Basename::dirname($name) } = $ts;
                    $file->{$name} = $ts;
                }
                }
        },
        File::Basename::dirname( $iKernel->get_repos_path(0) ),
    );

    bless {
        __dir            => $dir,
        __file           => $file,
        __kernel         => $iKernel,
        __really_removed => {},
        __removed        => {}
    }, $iClass;
}

sub get_dirs { $_[0]->{__dir} }

sub get_files { $_[0]->{__file} }

sub get_removed { [ keys %{ $_[0]->{__removed} } ] }

sub get_really_removed { [ keys %{ $_[0]->{__really_removed} } ] }

sub purge {
    my ( $zLogCollect, $file, $expires, $base, $confirm ) = @_;
    %{ $zLogCollect->{__really_removed} } = ();
    %{ $zLogCollect->{__removed} }        = ();
    $base ||= time();

    Img0ch::Kernel::intval($base)    or return 0;
    Img0ch::Kernel::intval($expires) or return 0;

    my $iKernel = $zLogCollect->{__kernel};
    my $expire  = $base - $expires;
    my $files   = $zLogCollect->{__file};
    my $regex   = $file =~ /\A\w+\z/xms ? qr{/$file\.\w+\z}xms : '';

    my $really = $zLogCollect->{__really_removed};
    my $remove = $zLogCollect->{__removed};

PURGE:
    while ( my ( $path, $time ) = each %$files ) {
        if ($regex) {
            $path =~ /$regex/xms or next PURGE;
        }
        if ( $time <= $expire ) {
            if ( !$confirm ) {
                unlink $path or $iKernel->throw_io_exception($path);
                $really->{$path} = 1;
            }
            else {
                $remove->{$path} = 1;
            }
        }
    }

    return 1;
}

1;
__END__
