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

package Zeromin::App::system;

use strict;

sub environment {
    my ($zApp) = @_;
    my $zUser = $zApp->user() || return { code => 1 };

    #    $zUser->can_create_bbs() or return { code => 1 };

    my $iConfig = $zApp->kernel()->get_config();
    return {
        code    => 0,
        content => {
            PerlVersion   => $],
            ServerOS      => $^O,
            ServerName    => $ENV{SERVER_NAME},
            ServerPort    => $ENV{SERVER_PORT},
            BasePath      => $iConfig->get('BBSPath'),
            Img0chVersion => Img0ch::Kernel->VERSION(),
        },
    };
}
*load = \&environment;

sub reload {
    my ($zApp) = @_;
    my $zUser = $zApp->user() || return { code => 1 };
    $zUser->can_create_bbs() or return { code => 1 };

    require Module::Refresh;
    my $mr = Module::Refresh->new();
    $mr->refresh();
    $zApp->logger( 1, 'RELOADED ALL MODULES' );

    return { code => 0 };
}

sub remove_template_cache {
    my ($zApp) = @_;
    my $zUser = $zApp->user() || return { code => 1 };
    $zUser->can_create_bbs() or return { code => 1 };

    require Img0ch::Template;
    my $iTemplate = Img0ch::Template->new(
        $zApp->kernel(),
        {   dir     => 'zeromin',
            file    => 'index',
            version => $zApp->request()->credit(),
        }
    );
    $iTemplate->remove_cache();
    $zApp->logger( 1, 'FLUSHED ALL TEMPLATE CACHES' );

    return { code => 0 };
}

sub repository {
    my ($zApp) = @_;
    my $zUser = $zApp->user() || return { code => 1 };
    $zUser->can_create_bbs() or return { code => 1 };

    my $iKernel  = $zApp->kernel();
    my $iConfig  = $iKernel->get_config();
    my $iRequest = $zApp->request();
    my $root     = $iConfig->get('RepositoryRoot');

    my $tar_dump = "${root}/img0ch-repository-dump.tar.gz";
    if ( -r $tar_dump ) {
        unlink $tar_dump or $iKernel->throw_io_exception($tar_dump);
    }
    my $zip_dump = "${root}/img0ch-repository-dump.zip";
    if ( -r $zip_dump ) {
        unlink $zip_dump or $iKernel->throw_io_exception($zip_dump);
    }

    require File::Find;
    my @files;
    File::Find::find(
        {   no_chdir => 1,
            untaint  => 1,
            wanted   => sub { push @files, $File::Find::name },
        },
        $root
    );
    if ( $iRequest->param('zip') ) {
        require Archive::Zip;
        Archive::Zip::setErrorHandler(
            sub {
                my $error = shift;
                $iKernel->throw_exception($error);
            }
        );
        my $zip = Archive::Zip->new();
        my $re  = qr/\A$root/xms;
        for my $file (@files) {
            my $path = $file;
            $file =~ s/$re/img0ch_repository_root/xms;
            $zip->addFileOrDirectory( $path, $file );
        }
        $zip->writeToFileNamed($zip_dump);
        $zApp->logger( 1, 'MADE REPOSITORY SNAPSHOT' );
    }
    else {
        require Archive::Tar;
        my $tar = Archive::Tar->new();
        my $re  = qr/\A$root/xms;
        for my $file (@files) {
            local ( *FH, $! );
            open *FH, "<${file}"    ## no critic
                or $iKernel->throw_io_exception($file);
            my $content = do { local $/ = undef; <FH> };
            close *FH or $iKernel->throw_io_exception($file);
            $file =~ s/$re/img0ch_repository_root/xms;
            $tar->add_data( $file, $content );
        }
        $tar->write( $tar_dump, 1 )
            or $iKernel->throw_exception( Archive::Tar->error() );
        $zApp->logger( 1, 'MADE REPOSITORY SNAPSHOT' );
    }

    return { code => 0 };
}

1;
__END__
