#/*
# *  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: UTF8Dat.pm 802 2007-06-10 12:47:54Z hikarin $
#

package Img0ch::Plugin::BBS::UTF8Dat;

use strict;
use Unicode::Japanese qw();

my $utf8bom = pack 'C*', ( 0xef, 0xbb, 0xbf );

sub sync {
    my ($iApp) = @_;
    my $from = $iApp->thread()->path();
    -r $from or return 1;

    my $iKernel  = $iApp->kernel();
    my $unijp    = Unicode::Japanese->new('');
    my $compress = $iApp->setting()->get('BBS_COMPRESS_DAT');
    _sync( $iKernel, $unijp, $from, $compress );
    return 1;
}

sub remove {
    my ( $iBBS, $plugin_id, $key ) = @_;

    require Img0ch::Thread;
    my $iThread = Img0ch::Thread->new( $iBBS, $key );
    _remove( $iBBS->get_kernel(), $iThread->path() );
    return 1;
}

*batch = \&repair;

sub repair {
    my ( $iBBS, $plugin_id, $info ) = @_;

    require Img0ch::Thread;
    require Unicode::Japanese;
    my $iKernel = $iBBS->get_kernel();
    my $iThread = Img0ch::Thread->new($iBBS);
    my $unijp   = Unicode::Japanese->new('');

    for my $key ( @{ $info->{recovered} } ) {
        $iThread->set_key($key);
        _sync( $iKernel, $unijp, $iThread->path(), 0 );
    }
    for my $key ( @{ $info->{removed} } ) {
        $iThread->set_key($key);
        _remove( $iKernel, $iThread->path() );
    }

    return 1;
}

sub _sync {
    my ( $iKernel, $unijp, $from, $compress ) = @_;
    my $encoding = $iKernel->get_encoding(1);
    local ( $!, *RFH, *WFH );

    open *RFH, "<${from}" or $iKernel->throw_io_exception($from); ## no critic
    if ($compress) {
        my $to = $from . '.utf8.gz';
        my $gz = Compress::Zlib::gzopen( $to, 'w' )
            or $iKernel->throw_io_exception($to);
        $gz->gzsetparams(
            Compress::Zlib::Z_BEST_COMPRESSION(),
            Compress::Zlib::Z_DEFAULT_STRATEGY(),
        );
        $gz->gzwrite($utf8bom) or $iKernel->throw_io_exception($to);
        while ( my $line = <RFH> ) {
            $gz->gzwrite( $unijp->set( $line, $encoding )->get() )
                or $iKernel->throw_io_exception($to);
        }
        $gz->gzclose();
    }
    else {
        my $to = $from . '.utf8';
        open *WFH, ">${to}" or $iKernel->throw_io_exception($to); ## no critic
        print {*WFH} $utf8bom or $iKernel->throw_io_exception($to);
        while ( my $line = <RFH> ) {
            print {*WFH} $unijp->set( $line, $encoding )->get()
                or $iKernel->throw_io_exception($to);
        }
        close *WFH or $iKernel->throw_io_exception($to);
    }
    close *RFH or $iKernel->throw_io_exception($from);
    return 1;
}

sub _remove {
    my ( $iKernel, $from ) = @_;
    my $utf8 = $from . '.utf8';
    my $gz   = $utf8 . '.gz';

    if ( -w $utf8 ) {
        unlink $utf8 or $iKernel->throw_io_exception($utf8);
    }
    if ( -w $gz ) {
        unlink $gz or $iKernel->throw_io_exception($gz);
    }
    return 1;
}

1;
__END__
