package Common::Permission;
use strict;

use lib '/app/tools/common/lib';
use Common::Client;
use Common::RSApp;
use Common::DB::Item::Permission;
use Common::XMLObject;

use base 'Common::XMLObject';

sub new {
    my $class = shift;

    my $self = {};
    bless $self, $class;

    my $accessLevel = shift;
    return $self->_init($accessLevel);
}

sub _init {
    my ( $self, $accessLevel ) = @_;

    $self->_readFromDB();
    $self->CreateObjectXML($accessLevel);

    return $self;
}

sub canAccess {
    my ( $self, $app, $area, $cmdToken, $accessLevel ) = @_;

    if ( !$self->{_permissions} ) {
        $self->_readFromDB();
    }

    return unless ($accessLevel);

    # See if the matching bit is set in the permission table.
    #
    return ( $self->{_permissions}{$app}{$area}{$cmdToken} & ( 1 << ( $accessLevel - 1 ) ) );
}

sub CreateObjectXML {
    my $self        = shift;
    my $accessLevel = shift;

    if ( !$self->{_permissions} ) {
        $self->_readFromDB();
    }
    return undef unless $self->{_permissions};

    foreach my $app ( keys %{ $self->{_permissions} } ) {
        my $areaHash = $self->{_permissions}{$app};
        foreach my $area ( keys %$areaHash ) {
            my $cmdHash = $areaHash->{$area};
            foreach my $cmd ( keys %$cmdHash ) {
                if ( $self->canAccess( $app, $area, $cmd, $accessLevel ) ) {
                    $self->{$app}{$area}{$cmd} = 1;
                }
            }
        }
    }
}

# Going to read the entire table from the database.
# We end up spewing it all out in XML anyway, so might as well
# be efficient about it and just hit the database once.
#
sub _readFromDB {
    my ($self) = @_;

    my $collection = Common::DB::Item::Permission->GetPermissions( clientTypeMask => Common::Client::Current()->TypeMask() );

    while ( my $permission = $collection->next() ) {
        $self->{_permissions}{ $permission->application }{ $permission->area }{ $permission->command } = $permission->access_level_mask;
    }
}

###
1;    # Play nicely.
###
