#/*
# *  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: init.pm 476 2007-04-10 13:20:28Z hikarin $
#

package Zeromin2::App::init;

use strict;

my @plugins = qw(
    Img0ch::Plugin::Filter::BanASCII::is_ascii_only
    Img0ch::Plugin::Filter::Host::check
    Img0ch::Plugin::Filter::IP::check
    Img0ch::Plugin::Filter::JPOnly::check
    Img0ch::Plugin::Filter::NGWord::check
    Img0ch::Plugin::Rewrite::AutoLink::from_bbs
    Img0ch::Plugin::Rewrite::AutoLink::from_read
    Img0ch::Plugin::Rewrite::AutoLink::from_mobile
    Img0ch::Plugin::Rewrite::Image::from_bbs
    Img0ch::Plugin::Rewrite::Image::from_read
    Img0ch::Plugin::Rewrite::Image::from_mobile
    Img0ch::Plugin::Rewrite::Quotation::from_bbs
    Img0ch::Plugin::Rewrite::Quotation::from_read
    Img0ch::Plugin::Rewrite::Quotation::from_mobile
    Img0ch::Plugin::Rewrite::Truncate::from_bbs
    Img0ch::Plugin::Rewrite::Truncate::from_read
    Img0ch::Plugin::Rewrite::Truncate::from_mobile
    Img0ch::Plugin::Upload::Thumbnail::create
);

sub install {
    my ($zApp) = @_;
    my $iKernel = $zApp->kernel();
    my $zUser = $zApp->user() || Zeromin::User->new($iKernel);

    if ( $zUser->is_initialized() ) {
        return $zApp->return_value( 16, 1 );
    }
    else {
        my $iRequest = $zApp->request();
        my $error    = {};
        my $param    = {};
        _validate( $zApp, $iRequest, $param, $error )
            or return $zApp->return_value( $error->{code}, 1 );

        my $iConfig = $iKernel->get_config();
        my $bbsPath = $iConfig->get('BBSPath');
        -d $bbsPath or return $zApp->return_value( 17, 1 );
        -r $bbsPath or return $zApp->return_value( 18, 1 );
        -w $bbsPath or return $zApp->return_value( 19, 1 );
        -x $bbsPath or return $zApp->return_value( 20, 1 );
        my $reposPath = $iConfig->get('RepositoryRoot');
        -d $reposPath or return $zApp->return_value( 21, 1 );
        -r $reposPath or return $zApp->return_value( 22, 1 );
        -w $reposPath or return $zApp->return_value( 23, 1 );
        -x $reposPath or return $zApp->return_value( 24, 1 );

        require Img0ch::BBS;
        my $iBBS   = Img0ch::BBS->new( $iKernel, { id => 0 } );
        my $iRepos = $iBBS->get_common_repos();
        my $path   = $iConfig->get('SystemPath') . '/error.txt';

        local ( $!, *FH );
        open *FH, "<${path}"    ## no critic
            or $iKernel->throw_io_exception($path);
        while ( my $line = <FH> ) {
            chomp $line;
            my ( $errid, $errmsg ) = ( split '<>', $line )[ 0, 2 ];
            $errid  ||= '';
            $errmsg ||= '';
            $iRepos->set( "I:E.${errid}", $errmsg );
        }
        close *FH or $iKernel->throw_io_exception($path);
        $iRepos->save();

        $zUser->add_group(
            {   bbs       => 0,
                name      => 'Administrators',
                privilege => {
                    user     => 127,
                    cap      => 127,
                    bbs      => 127,
                    thread   => 127,
                    res      => 127,
                    pool     => 127,
                    archive  => 127,
                    setting  => 127,
                    subject  => 127,
                    meta     => 127,
                    control  => 127,
                    category => 127,
                    view     => 127,
                    plugin   => 127,
                },
                role => 2,
            }
        );
        $zUser->save();
        $zUser->add(
            {   name => $param->{user_name},
                mail => $param->{user_mail},
                pass => $param->{user_pass},
                gid  => $zUser->get_group_id('Administrators'),
            }
        );
        $zUser->save();

        require Zeromin::Category;
        my $zCategory = Zeromin::Category->new($iKernel);
        $zCategory->add('Generic');
        $zCategory->save();

        if ( $param->{create_bbs} ) {
            require Zeromin::BBS;
            my $bbs = $param->{bbs_dir};
            my $zBBS = Zeromin::BBS->new( $iKernel, { bbs => $bbs } );
            $zBBS->create(
                {   title      => $param->{bbs_name},
                    sub_title  => $param->{bbs_sub_name},
                    uploadable => $param->{bbs_uploadable},
                }
            );
        }

        if ( $param->{create_cap} ) {
            require Zeromin::Cap;
            my $zCap = Zeromin::Cap->new( $iKernel, '' );
            $zCap->add_group(
                {   bbs       => 0,
                    name      => 'Administrator',
                    privilege => 1023,
                }
            );
            $zCap->save();
            $zCap->add(
                {   name => $param->{cap_name},
                    pass => $param->{cap_pass},
                    gid  => $zCap->get_group_id('Administrator'),
                }
            );
            $zCap->save();
        }

        my $zPlugin = Zeromin::Plugin->new($iKernel);
        $zPlugin->load();
        $zPlugin->search();
        $zPlugin->save();
        map { $zPlugin->enable($_) } @plugins;
        $zPlugin->save();

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

sub _validate {
    my ( $zApp, $iRequest, $param, $error ) = @_;
    my $uname = $iRequest->param('user_name');
    my $umail = $iRequest->param('user_mail');
    my $upass = $iRequest->param('user_pass');
    my $uconf = $iRequest->param('user_confirm');
    $zApp->add_template_param(
        {   UserName    => $uname,
            UserMail    => $umail,
            UserPass    => $upass,
            UserConfirm => $uconf
        }
    );

    require Unicode::Japanese;
    my $unijp = Unicode::Japanese->new();
    if ( $uname =~ /\A\s*\z/xms ) {
        %{$error} = ( code => 2 );
        return 0;
    }
    elsif ( $umail =~ /\A\s*\z/xms ) {
        %{$error} = ( code => 3 );
        return 0;
    }
    elsif ( $upass =~ /\A\s*\z/xms ) {
        %{$error} = ( code => 4 );
        return 0;
    }
    elsif ( $uconf =~ /\A\s*\z/xms ) {
        %{$error} = ( code => 5 );
        return 0;
    }
    elsif ( $upass ne $uconf ) {
        %{$error} = ( code => 6 );
        return 0;
    }
    elsif ( $umail !~ /\A[\w\.]+\@[\w\.]+\z/xms ) {
        %{$error} = ( code => 7 );
        return 0;
    }

    my ( $bbsdir, $bname, $bsname );
    if ( $param->{create_bbs} = $iRequest->param('create_bbs') ) {
        $bbsdir = $iRequest->param('dir');
        $bname  = $iRequest->param('BBS_TITLE');
        $bsname = $iRequest->param('BBS_SUBTITLE');
        $zApp->add_template_param(
            {   BBSDir     => $bbsdir,
                BBSName    => $bname,
                BBSSubname => $bsname
            }
        );

        if ( $bbsdir =~ /\A\s*\z/xms ) {
            %{$error} = ( code => 8 );
            return 0;
        }
        elsif ( $bname =~ /\A\s*\z/xms ) {
            %{$error} = ( code => 9 );
            return 0;
        }
        elsif ( $bsname =~ /\A\s*\z/xms ) {
            %{$error} = ( code => 10 );
            return 0;
        }
        elsif ( $bbsdir !~ /\A[\w\-\.]+\z/xms or $bbsdir eq 'test' ) {
            %{$error} = ( code => 11 );
            return 0;
        }
    }

    my ( $cname, $cpass, $cconf );
    if ( $param->{create_cap} = $iRequest->param('create_cap') ) {
        $cname = $iRequest->param('cap_name');
        $cpass = $iRequest->param('cap_pass');
        $cconf = $iRequest->param('cap_confirm');
        $zApp->add_template_param(
            {   CapName    => $cname,
                CapPass    => $cpass,
                CapConfirm => $cconf
            }
        );

        if ( $cname =~ /\A\s*\z/xms ) {
            %{$error} = ( code => 12 );
            return 0;
        }
        elsif ( $cpass =~ /\A\s*\z/xms ) {
            %{$error} = ( code => 13 );
            return 0;
        }
        elsif ( $cconf =~ /\A\s*\z/xms ) {
            %{$error} = ( code => 14 );
            return 0;
        }
        elsif ( $cpass ne $cconf ) {
            %{$error} = ( code => 15 );
            return 0;
        }
    }

    $param->{user_name}      = $uname;
    $param->{user_mail}      = $umail;
    $param->{user_pass}      = $upass;
    $param->{bbs_dir}        = $bbsdir;
    $param->{bbs_name}       = $unijp->set( $bname, 'utf8' )->sjis();
    $param->{bbs_sub_name}   = $unijp->set( $bsname, 'utf8' )->sjis();
    $param->{bbs_uploadable} = $iRequest->param('upload');
    $param->{cap_name}       = $unijp->set( $cname, 'utf8' )->sjis();
    $param->{cap_pass}       = $cpass;
    1;
}

1;
__END__
