#/*
# *  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 1936 2010-01-21 00:55:51Z hikarin $
#

package Zeromin2::App::system;

use strict;

sub logout {
    my ($zApp) = @_;
    $zApp->privilege(undef) or return $zApp->return_value(1);

    my $session = $zApp->session();
    $session->close();
    $session->delete();
    $zApp->add_template_param( { Logout => 1 } );
    $zApp->logger( 1, 'LOGOUT' );
    return $zApp->return_value(0);
}

sub load {
    my ($zApp) = @_;
    $zApp->privilege('can_create_bbs') or return $zApp->return_value(1);

    my $iConfig = $zApp->kernel()->get_config();
    my $data    = {
        PerlVersion   => $],
        ServerOS      => $^O,
        ServerName    => $ENV{SERVER_NAME},
        ServerPort    => $ENV{SERVER_PORT},
        BasePath      => $iConfig->get('BBSPath'),
        Img0chVersion => Img0ch::Kernel->VERSION(),
    };

    $zApp->add_template_param($data);
    return $zApp->return_value( 0, $data );
}

sub reload_modules {
    my ($zApp) = @_;
    $zApp->check_csrf() or return $zApp->return_value(1);
    $zApp->privilege('can_create_bbs') or return $zApp->return_value(1);

    require Module::Refresh;
    my $mr = Module::Refresh->new();
    $mr->refresh();

    $zApp->logger( 1, 'RELOADED ALL MODULES' );
    return $zApp->return_value(0);
}

sub remove_template_caches {
    my ($zApp) = @_;
    $zApp->check_csrf() or return $zApp->return_value(1);
    $zApp->privilege('can_create_bbs') or return $zApp->return_value(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 $zApp->return_value(0);
}

sub dump_repository {
    my ($zApp) = @_;
    $zApp->check_csrf() or return $zApp->return_value(1);
    $zApp->privilege('can_create_bbs') or return $zApp->return_value(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) {
            my $fh = $iKernel->get_read_file_handle($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 $zApp->return_value(0);
}

sub test_connect_pop3 {
    my ($zApp) = @_;
    $zApp->privilege('can_create_bbs') or return $zApp->return_value(1);

    require Mail::POP3Client;
    my $iConfig = $zApp->kernel()->get_config();
    my $pop3    = Mail::POP3Client->new(
        HOST =>
            ( $iConfig->get('pop3.server') || $iConfig->get('POP3Server') ),
        PORT => ( $iConfig->get_int('pop3.port') || 110 ),
        USESSL => ( $iConfig->get('pop3.ssl') ? 1 : 0 ),
        TIMEOUT   => ( $iConfig->get_int('pop3.timeout') || 5 ),
        AUTH_MODE => ( $iConfig->get('pop3.auth')        || 'BEST' ),
    );
    $pop3->User( $iConfig->get('pop3.user') || $iConfig->get('POP3User') );
    $pop3->Pass( $iConfig->get('pop3.pass') || $iConfig->get('POP3Pass') );

    my $count = -1;
    $pop3->Connect() > 0 and $count = $pop3->Count();
    my $message = $pop3->Message();
    $pop3->Close();

    my $data = {
        POP3ConnectOK => ( $count != -1 ),
        POP3Message   => $message,
        POP3MailCount => $count,
    };

    $zApp->add_template_param($data);
    return $zApp->return_value( 0, $data );
}

1;
__END__
