#/*
# *  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 218 2007-02-12 13:30:13Z hikarin $
#

package Zeromin::App::init;

use strict;

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

    if ( $zUser->is_initialized() ) {
        return { installOK => 0, reason => 'SCHEMA HAS INSTALLED' };
    }
    else {
        my $iRequest = $zApp->request();
        my $error    = {};
        my $param    = {};
        _validate( $iRequest, $param, $error ) or return $error;

        require Img0ch::BBS;
        my $iBBS   = Img0ch::BBS->new( $iKernel, { id => 0 } );
        my $iRepos = $iBBS->get_common_repos();
        my $path   = $iKernel->get_config()->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();
        }

        return { installOK => 1, reason => '' };
    }
}

sub _validate {
    my ( $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');

    require Unicode::Japanese;
    my $unijp = Unicode::Japanese->new();
    if ( $uname =~ /\A\s*\z/xms ) {
        %{$error} = (
            installOK => 0,
            reason    => 'NO USER NAME',
        );
        return 0;
    }
    elsif ( $umail =~ /\A\s*\z/xms ) {
        %{$error} = (
            installOK => 0,
            reason    => 'NO USER MAIL',
        );
        return 0;
    }
    elsif ( $upass =~ /\A\s*\z/xms ) {
        %{$error} = (
            installOK => 0,
            reason    => 'NO USER PASS',
        );
        return 0;
    }
    elsif ( $uconf =~ /\A\s*\z/xms ) {
        %{$error} = (
            installOK => 0,
            reason    => 'NO USER PASS CONFIRM',
        );
        return 0;
    }
    elsif ( $upass ne $uconf ) {
        %{$error} = (
            installOK => 0,
            reason    => 'PASS AND CONFIRM DOES NOT MATCH'
        );
        return 0;
    }
    elsif ( $umail !~ /\A[\w\.]+\@[\w\.]+\z/xms ) {
        %{$error} = (
            installOK => 0,
            reason    => 'INVALID USER MAIL'
        );
        return 0;
    }

    my ( $bbsdir, $bname, $bsname );
    if ( $param->{create_bbs} = $iRequest->param('create_bbs') ) {
        $bbsdir = $iRequest->param('bbs_dir');
        $bname  = $iRequest->param('bbs_name');
        $bsname = $iRequest->param('bbs_sub_name');
        if ( $bbsdir =~ /\A\s*\z/xms ) {
            %{$error} = (
                installOK => 0,
                reason    => 'NO BBS DIR',
            );
            return 0;
        }
        elsif ( $bname =~ /\A\s*\z/xms ) {
            %{$error} = (
                installOK => 0,
                reason    => 'NO BBS NAME',
            );
            return 0;
        }
        elsif ( $bsname =~ /\A\s*\z/xms ) {
            %{$error} = (
                installOK => 0,
                reason    => 'NO BBS SUB NAME',
            );
            return 0;
        }
        elsif ( $bbsdir !~ /\A[\w\-\.]+\z/xms or $bbsdir eq 'test' ) {
            %{$error} = (
                installOK => 0,
                reason    => 'INVALID BBS DIR',
            );
            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');
        if ( $cname =~ /\A\s*\z/xms ) {
            %{$error} = (
                installOK => 0,
                reason    => 'NO CAP NAME',
            );
            return 0;
        }
        elsif ( $cpass =~ /\A\s*\z/xms ) {
            %{$error} = (
                installOK => 0,
                reason    => 'NO CAP PASS',
            );
            return 0;
        }
        elsif ( $cconf =~ /\A\s*\z/xms ) {
            %{$error} = (
                installOK => 0,
                reason    => 'NO CAP PASS CONFIRM',
            );
            return 0;
        }
        elsif ( $cpass ne $cconf ) {
            %{$error} = (
                installOK => 0,
                reason    => 'PASS AND CONFIRM DOES NOT MATCH'
            );
            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('bbs_uploadable');
    $param->{cap_name}       = $unijp->set( $cname, 'utf8' )->sjis();
    $param->{cap_pass}       = $cpass;
    1;
}

1;
__END__
