#/*
# *  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: cgroup.pm 390 2007-03-20 14:06:06Z hikarin $
#

package Zeromin2::App::cgroup;

use strict;

sub load {
    my ($zApp) = @_;
    $zApp->privilege('can_enter_cap_section')
        or return $zApp->return_value( 1, [] );
    return $zApp->return_value( 0,
        _cap($zApp)->get_groups_with_page( $zApp->page_param() ) );
}

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

    my $zCap     = _cap($zApp);
    my $iRequest = $zApp->request();
    my $error    = {};
    my $param    = {};

    _validate_cgroup_param( $zApp, $zCap, $iRequest, $param, $error )
        or return $zApp->return_value( $error->{code} );
    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} ) {
        $zApp->privilege('can_edit_cgroup') or return $zApp->return_value(1);
        $zCap->edit_group(
            $id,
            {   name      => $name,
                bbs       => $bbs,
                privilege => $privilege,
            }
        ) or return $zApp->return_value(8);
        $zCap->save();
        $zApp->logger(
            1,
            'EDIT CAP GROUP: %s privilege-bit %d and belongs %d',
            [ $name, $privilege, $bbs ],
        );
        $zApp->add_template_param( { Done_cgroup_edit => 1 } );
        $zApp->return_value(0);
    }
    else {
        $zApp->privilege('can_create_cgroup')
            or return $zApp->return_value(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 ],
        );
        $zApp->add_template_param( { Done_cgroup_create => 1 } );
        $zApp->return_value( 0, $zCap->get_group_id($name) );
    }
}

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

    my $zCap   = _cap($zApp);
    my $status = {};
    my @ids    = $zApp->request()->param('id');
    scalar @ids or return $zApp->return_value(2);

    for my $id (@ids) {
        if ( $zCap->remove_group($id) ) {
            $zApp->logger( 1, 'REMOVE CAP GROUP: %s', [$id] );
            $status->{$id} = 1;
        }
        else {
            $zApp->logger( 0, 'TRIED REMOVING INEXIST CAP GROUP: %s', [$id] );
            $status->{$id} = 0;
        }
    }

    $zCap->save();
    return $zApp->return_value( 0, $status );
}

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

    require Zeromin::BBS;
    my $zBBS = Zeromin::BBS->new( $zApp->kernel(), { bbs => '' } );
    my ( $unijp, $encoding ) = $zApp->unijp();

    $zApp->add_template_param( { BBSList => $zBBS->all($unijp) } );
    return $zApp->return_value(0);
}

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

    require Zeromin::BBS;
    my $zCap  = _cap($zApp);
    my $group = $zCap->get_group( $zApp->request()->param('id') );
    my $zBBS  = Zeromin::BBS->new( $zApp->kernel(), { bbs => '' } );

    my ( $unijp, $encoding ) = $zApp->unijp();
    my $allBBS     = $zBBS->all($unijp);
    my $allBelongs = $group->{bbs};
    for my $bbs (@$allBBS) {
        for my $belong (@$allBelongs) {
            $bbs->{id} == $belong and $bbs->{selected} = 1;
        }
    }

    my $privilege       = {};
    my $privilege_value = $group->{privilege};
    for my $privilege_bit ( 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 ) {
        $privilege->{"Privilege_${privilege_bit}"}
            = $privilege_value & $privilege_bit ? 1 : 0;
    }

    $zApp->add_template_param(
        {   BBSList  => $allBBS,
            IsGlobal => ( $allBelongs->[0] == 0 ? 1 : 0 ),
            %$privilege,
            %$group
        }
    );
    return $zApp->return_value(0);
}

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

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

    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');
    $iRequest->param('all') and @bbs = (0);

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

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

1;
__END__
