#/*
# *  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: cap.pm 251 2007-02-17 13:22:39Z hikarin $
#

package Zeromin::App::cap;

use strict;

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

    if ( $iRequest->param('type') eq 'individual' ) {
        $zUser->can_enter_cap_section() or return { code => 1 };
        require Unicode::Japanese;
        my $unijp = Unicode::Japanese->new();
        $ret = _cap($zApp)->get_caps($unijp);
    }
    else {
        $zUser->can_enter_cgroup_section() or return { code => 1 };
        $ret = _cap($zApp)->get_groups();
    }

    if ( my $offset = $iRequest->param_int('offset') ) {
        my $item = $iRequest->param_int('item') || 10;
        $ret = $zApp->paging_from_array( $ret, $offset, $item );
    }
    return { code => 0, content => $ret };
}

sub save {
    my ($zApp) = @_;
    my $zUser    = $zApp->user() or return { code => 1 };
    my $iRequest = $zApp->request();
    my $zCap     = _cap($zApp);
    my $error    = {};
    my $param    = {};

    if ( $iRequest->param('type') eq 'individual' ) {
        _validate_cap_param( $zApp, $zCap, $param, $error ) or return $error;
        my $id   = $param->{id};
        my $cap  = $zCap->get_cap($id);
        my $name = $param->{name};
        my $pass = $param->{pass};
        my $gid  = $param->{gid};
        if ( defined $cap->{id} ) {
            $zUser->can_edit_cap() or return { code => 1 };
            $zCap->edit(
                $id,
                {   name => $name,
                    gid  => $gid,
                }
            );
            $zCap->save();
            $zApp->logger(
                1,
                'EDIT CAP: from %s to %s belongs %d',
                [ $cap->{name}, $name, $gid ],
            );
            { code => 0 };
        }
        else {
            $zUser->can_create_cap() or return { code => 1 };
            $zCap->add(
                {   name => $name,
                    pass => $pass,
                    gid  => $gid,
                }
            ) or return { code => 8 };
            $zCap->save();
            $zApp->logger(
                1,
                'CREATE CAP: %s with %s belongs %d',
                [ $name, $pass, $gid ],
            );
            { code => 0, id => $zCap->get_cap_pass($name) };
        }
    }
    else {
        _validate_cgroup_param( $zApp, $zCap, $param, $error )
            or return $error;
        my $id        = $iRequest->param('id');
        my $cgroup    = $zCap->get_group($id);
        my $name      = $param->{name};
        my $bbs       = $param->{bbs};
        my $privilege = $param->{privilege};
        if ( $cgroup->{id} ) {
            $zUser->can_edit_cgroup() or return { code => 1 };
            $zCap->edit_group(
                $id,
                {   name      => $name,
                    bbs       => $bbs,
                    privilege => $privilege,
                }
            ) or return { code => 8 };
            $zCap->save();
            $zApp->logger(
                1,
                'EDIT CAP GROUP: %s privilege-bit %d and belongs %d',
                [ $name, $privilege, $bbs ],
            );
            { code => 0 };
        }
        else {
            $zUser->can_create_cgroup() or return { code => 1 };
            $zCap->add_group(
                {   name      => $name,
                    bbs       => $bbs,
                    privilege => $privilege,
                }
            );
            $zCap->save();
            $zApp->logger(
                1,
                'CREATE CAP GROUP: %s privilege-bit %d and belongs %d',
                [ $name, $privilege, $bbs ],
            );
            { code => 0, id => $zCap->get_group_id($name) };
        }
    }
}

sub remove {
    my ($zApp) = @_;
    my $zUser    = $zApp->user() or return { code => 1 };
    my $iRequest = $zApp->request();
    my $zCap     = _cap($zApp);
    my $status   = {};
    my ( $type, $method );

    if ( $iRequest->param('type') eq 'individual' ) {
        $zUser->can_remove_cap() or return { code => 1 };
        $type   = 'CAP';
        $method = 'remove';
    }
    else {
        $zUser->can_remove_cgroup() or return { code => 1 };
        $type   = 'CAP GROUP';
        $method = 'remove_group';
    }

    my @ids = $iRequest->param('id');
    for my $id (@ids) {
        $id = Img0ch::Kernel::intval($id);
        if ( $zCap->$method($id) ) {
            $zApp->logger( 1, "REMOVE $type: \%s", [$id] );
            $status->{$id} = 1;
        }
        else {
            $zApp->logger( 0, "TRIED REMOVING INEXIST $type: \%s", [$id] );
            $status->{$id} = 0;
        }
    }
    $zCap->save();
    { code => 0, removed => $status };
}

sub get {
    my ($zApp) = @_;
    my $zUser    = $zApp->user() || return { code => 1 };
    my $iRequest = $zApp->request();
    my $id       = _cap($zApp)->param('id');

    if ( $iRequest->param('type') eq 'individual' ) {
        $zUser->can_enter_cap_section() or return { code => 1 };
        return _cap($zApp)->get_cap($id);
    }
    else {
        $zUser->can_enter_cgroup_section() or return { code => 1 };
        return _cap($zApp)->get_group($id);
    }
}

sub _cap {
    require Zeromin::Cap;
    my $zApp = shift;
    my $zCap = Zeromin::Cap->new( $zApp->bbs() || $zApp->kernel() );
    $zCap->load();
    return $zCap;
}

sub _validate_cap_param {
    my ( $zApp, $zCap, $param, $error ) = @_;
    my $iRequest = $zApp->request();

    my $name = $iRequest->param('name');
    if ( $name eq '' ) {
        $zApp->logger( 0, 'NO CAP NAME WAS SET' );
        %{$error} = ( code => 2 );
        return 0;
    }
    my $group = $iRequest->param_int('group');
    if ( !$group ) {
        $zApp->logger( 0, 'NO CAP GROUP WAS SET' );
        %{$error} = ( code => 3 );
        return 0;
    }
    if ( $zCap->get_group_name($group) eq '' ) {
        $zApp->logger( 0, 'INVALID CAP GROUP WAS SET' );
        %{$error} = ( code => 7 );
        return 0;
    }

    my $id = $iRequest->param('id');
    if ( !$id ) {
        my $pass = $iRequest->param('pass');
        if ( $pass eq '' ) {
            $zApp->logger( 0, 'NO CAP PASS WAS SET' );
            %{$error} = ( code => 4 );
            return 0;
        }
        my $conf = $iRequest->param('confirm');
        if ( $conf eq '' ) {
            $zApp->logger( 0, 'NO CAP CONFIRM PASS WAS SET' );
            %{$error} = ( code => 5 );
            return 0;
        }
        if ( $pass ne $conf ) {
            $zApp->logger( 0, 'NOT EQUAL CAP PASS AND CAP CONFIRM PASS' );
            %{$error} = ( code => 6 );
            return 0;
        }
        $param->{pass} = $pass;
    }

    require Unicode::Japanese;
    $param->{id}   = $id;
    $param->{name} = Unicode::Japanese->new($name)->sjis;
    $param->{gid}  = $group;
    1;
}

sub _validate_cgroup_param {
    my ( $zApp, $zCap, $param, $error ) = @_;
    my $iRequest = $zApp->request();

    my $name = $iRequest->param('name');
    if ( $name eq '' ) {
        $zApp->logger( 0, 'NO CAP GROUP NAME WAS SET' );
        %$error = ( code => 2 );
        return 0;
    }

    my @bbs           = $iRequest->param('bbs');
    my @privilege     = $iRequest->param_int('p');
    my $privilege_sum = 0;
    map { $privilege_sum += $_ } @privilege;

    $param->{name}      = $name;
    $param->{bbs}       = \@bbs;
    $param->{privilege} = $privilege_sum;
    1;
}

1;
__END__
