
#                                      Copyright 2024 WebPros International, LLC
#                                                           All rights reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited.

package Whostmgr::360Monitoring::Util;

use cPstrict;
use autodie;
use experimental 'builtin';

use Whostmgr::360Monitoring::Moo ();
use Whostmgr::360Monitoring::Util::PackagesAndFiles ':all';

# That package which tracks roles
use constant {
    ROLE_NAMESPACE   => 'Whostmgr::360Monitoring::Agent::Plugins::Roles',
    PLUGIN_NAMESPACE => 'Whostmgr::360Monitoring::Agent::Plugins',
    NOOP             => sub { 1 }
};

sub get_role_package   ($role)   { concat_packages( ROLE_NAMESPACE,   ucfirst( lc($role) ) ); }
sub get_plugin_package ($plugin) { concat_packages( PLUGIN_NAMESPACE, ucfirst( lc($plugin) ) ); }

sub get_all_classes_under ($package) {
    my $dir = class_to_dir($package);
    opendir( my $dh, $dir );
    my @plugins = map { concat_packages( $package, $_ ) }
      sort
      grep s/.pm$//,
      readdir($dh);
    \@plugins;
}

# A list of roles
use constant ROLES => get_all_classes_under(ROLE_NAMESPACE);

sub get_class_attrs ( $class, $filter = NOOP, $list = Whostmgr::360Monitoring::Moo::LIST_NAME ) {
    $class = builtin::blessed($class) if ref $class;
    no strict "refs";
    my %attrs;
    while ( my ( $name, $options ) = each %{"$class\::$list"} ) {
        $attrs{$name} = $options if $filter->($options);
    }
    \%attrs;
}

sub get_all_attrs ( $classOrObj, $filter = NOOP, $list = Whostmgr::360Monitoring::Moo::LIST_NAME ) {
    my $attrs = get_class_attrs( $classOrObj, $filter, $list );

    my $roles = get_all_roles( $classOrObj, $filter, $list );
    foreach my $role ( keys %$roles ) {
        my $roledb = $roles->{$role};
        while ( my ( $attr, $options ) = each %$roledb ) {
            $attrs->{$attr} = $options if $filter->($options);
        }
    }

    $attrs;
}

sub get_all_roles ( $classOrObj, $filter = NOOP, $list = Whostmgr::360Monitoring::Moo::LIST_NAME ) {
    state $roles = do {
        my %db;
        foreach my $role ( ROLES->@* ) {
            my $attrs = get_class_attrs( $role, $filter, $list );
            $db{$role} = $attrs;
        }
        \%db;
    };

    my %classRoles;
    foreach my $role ( keys %$roles ) {
        next if $classOrObj eq $role;
        if ( $classOrObj->DOES($role) ) {
            $classRoles{$role} = $roles->{$role};
        }
    }

    \%classRoles;

}

1;

__END__

=head1 NAME

Whostmgr::360Monitoring::Util

=head2 FUNCTIONS

=over 12

=item get_role_package( $role )

The call C<get_role_package('Enableable')> returns L<Whostmgr::360Monitoring::Agent::Plugins::Roles::Enableable>.

=item get_plugin_package( $package )

The call C<get_plugin_package('cpanel')> returns L<Whostmgr::360Monitoring::Agent::Plugins::Cpanel>.

=item get_all_classes_under( $package )

Gets all the plugins under the directory the package resolves to. Useful for finding all roles, or plugins.

=item get_class_attrs( $classOrObj, [$filter] )

Gets just the attributes for the class

=item get_all_attrs( $classOrObj, [$filter] )

Gets just the attributes from the class and the role

=item get_all_roles( $classOrObj )

Gets all the roles

=back
