#/*
# *  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 1038 2007-09-02 12:31:15Z hikarin $
#

package Zeromin2::App::cap;

use strict;

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

    my ( $unijp, $encoding ) = $zApp->unijp();
    return $zApp->return_value( 0,
        _cap($zApp)->get_caps_with_page( $unijp, $zApp->page_param('cap') ) );
}

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

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

    _validate_cap_param( $zApp, $zCap, $iRequest, $param, $error )
        or return $zApp->return_value( $error->{code} );
    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} ) {
        $zApp->privilege('can_edit_cap') or return $zApp->return_value(1);
        $zCap->edit(
            $id,
            {   name => $name,
                gid  => $gid,
            }
        );
        $zCap->save();
        $zApp->logger(
            1,
            'EDIT CAP: from %s to %s belongs %d',
            [   $iKernel->get_encoded_str( $cap->{name}, 'utf8' ),
                $iKernel->get_encoded_str( $name,        'utf8' ),
                $gid
            ],
        );
        $zApp->add_template_param( { Done_cap_edit => 1 } );
        $zApp->return_value(0);
    }
    else {
        $zApp->privilege('can_create_cap') or return $zApp->return_value(1);
        $zCap->add(
            {   name => $name,
                pass => $pass,
                gid  => $gid,
            }
        ) or return $zApp->return_value(8);
        $zCap->save();
        $zApp->logger(
            1,
            'CREATE CAP: %s with %s belongs %d',
            [ $iKernel->get_encoded_str( $name, 'utf8' ), $pass, $gid ],
        );
        $zApp->add_template_param( { Done_cap_create => 1 } );
        $zApp->return_value( 0, $zCap->get_cap_pass($name) );
    }
}

sub remove {
    my ($zApp) = @_;
    $zApp->check_csrf() or return $zApp->return_value(1);
    $zApp->privilege('can_remove_cap')
        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($id) ) {
            $zApp->logger( 1, 'REMOVE CAP: %s', [$id] );
            $status->{$id} = 1;
        }
        else {
            $zApp->logger( 0, 'TRIED REMOVING INEXIST CAP: %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);

    $zApp->add_template_param( { Groups => _cap($zApp)->get_groups() } );
    return $zApp->return_value(0);
}

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

    my $zCap = _cap($zApp);
    my ( $unijp, $encoding ) = $zApp->unijp();
    my $cap
        = $zCap->get_cap( $zApp->request()->param('id'), $unijp, $encoding );

    my $gid   = $cap->{gid};
    my $group = $zCap->get_groups();
    for my $grp (@$group) {
        $grp->{id} == $gid and $grp->{selected} = 1;
    }

    $zApp->add_template_param( { Groups => $group, %$cap } );
    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_cap_param {
    my ( $zApp, $zCap, $iRequest, $param, $error ) = @_;

    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;
    }

    my $iKernel = $zApp->kernel();
    $param->{id}   = $id;
    $param->{name} = $iKernel->get_encoded_str( $name, undef, 'utf8' );
    $param->{gid}  = $group;

    return 1;
}

1;
__END__
