#/*
# *  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: Simple.pm 363 2007-03-16 15:11:10Z hikarin $
#

package Img0ch::Maple::Simple;

use strict;

sub new {
    my ( $iClass, $iKernel, $path ) = @_;
    bless {
        __data     => {},
        __filename => $path,
        __kernel   => $iKernel,
    }, $iClass;
}

sub DESTROY { }

sub load {
    my ( $iRepos, $path ) = @_;
    my $iKernel = $iRepos->{__kernel};
    my $data    = {};

    $path ||= $iRepos->{__filename};
    -r $path or return 1;
    local ( $!, *FH );

    open *FH, "<${path}" or $iKernel->throw_io_exception($path);  ## no critic
    while ( my $line = <FH> ) {
        chomp $line;
        my ( $key, $value ) = split '=', $line, 2;
        $data->{$key} = $value;
    }
    close *FH or $iKernel->throw_io_exception($path);
    %{ $iRepos->{__data} } = %{$data};
    return 1;
}

sub save {
    my ( $iRepos, $path ) = @_;
    my $iKernel = $iRepos->{__kernel};
    my $data    = $iRepos->{__data};

    $path ||= $iRepos->{__filename};
    my $temp    = $path . '.tmp';
    my $LOCK_EX = 2;
    eval {
        require Fcntl;
        $LOCK_EX = Fcntl::LOCK_EX();
    };

    eval {
        local ( $!, *FH );
        open *FH, ">${temp}"    ## no critic
            or $iKernel->throw_io_exception($path);
        flock *FH, $LOCK_EX;
        while ( my ( $key, $value ) = each %{$data} ) {
            print {*FH} $key, '=', $value, "\n"
                or $iKernel->throw_io_exception($path);
        }
        close *FH or $iKernel->throw_io_exception($path);
        rename $temp, $path or $iKernel->throw_io_exception($path);
    };
    if ( my $exception = $@ ) {
        unlink $temp or $iKernel->throw_io_exception($temp);
        die $exception, "\n";
    }
    return 1;
}

sub set {
    my ( $iRepos, $key, $value ) = @_;
    $iRepos->{__data}->{$key} = $value;
    return;
}

sub set_binary {
    my ( $iRepos, $key, $value ) = @_;
    if ( eval "require MIME::Base64; 1" ) {
        $iRepos->set( $key, MIME::Base64::encode_base64( $value, '' ) );
    }
    else {
        require MIME::Base64::Perl;
        $iRepos->set( $key, MIME::Base64::Perl::encode_base64( $value, '' ) );
    }
}

sub get {
    my ( $iRepos, $key ) = @_;
    return $iRepos->{__data}->{$key} || '';
}

sub get_binary {
    my ( $iRepos, $key ) = @_;
    if ( eval "require MIME::Base64; 1" ) {
        return MIME::Base64::decode_base64( $iRepos->get($key) );
    }
    else {
        require MIME::Base64::Perl;
        return MIME::Base64::Perl::decode_base64( $iRepos->get($key) );
    }
}

sub decode_binary {
    my ( $iRepos, $value ) = @_;
    $value or return '';
    if ( eval "require MIME::Base64; 1" ) {
        return MIME::Base64::decode_base64($value);
    }
    else {
        require MIME::Base64::Perl;
        return MIME::Base64::Perl::decode_base64($value);
    }
}

sub is_binary_safe {0}

sub get_int { Img0ch::Kernel::intval( $_[0]->get( $_[1] ) ) }

sub remove {
    my ( $iRepos, $key ) = @_;
    return delete $iRepos->{__data}->{$key};
}

sub iterate {
    my ( $iRepos, $code_ref, @args ) = @_;
    my $data = $iRepos->{__data};

    while ( my ( $key, $value ) = each %{$data} ) {
        my $status = $code_ref->( $key, \$value, @args );
        if ( $status > 0 ) {
            $iRepos->set( $key, $value );
        }
        elsif ( $status < 0 ) {
            $iRepos->remove($key);
        }
    }
    return 1;
}

1;
__END__
