#! /usr/bin/env perl
# vim: set filetype=perl ts=4 sw=4 sts=4 et:
use common::sense;
use Term::ANSIColor;

use File::Basename;
use lib dirname(__FILE__) . '/../../../lib/perl';
use OVH::Result;
use OVH::Bastion;
use OVH::Bastion::Plugin qw( :DEFAULT help );

# globally allow sys_getpw* and sys_getgr* cache use
$ENV{'PW_GR_CACHE'} = 1;

my $remainingOptions = OVH::Bastion::Plugin::begin(
    argv    => \@ARGV,
    header  => "group list",
    options => {
        'all'       => \my $all,
        'exclude=s' => \my @excludes,
        'include=s' => \my @includes,
    },
    helptext => <<'EOF',
List the groups available on this bastion

Usage: --osh SCRIPT_NAME [--all] [--exclude|--include PATTERN [--exclude|--include PATTERN ..]]

  --all               List all groups, even those to which you don't have access
  --include PATTERN  Only list groups that match the given PATTERN (see below)
                        This option can be used multiple times to refine results
  --exclude PATTERN  Omit groups that match the given PATTERN string (see below)
                        This option can be used multiple times.
                        Note that --exclude takes precedence over --include

**Note:** PATTERN supports the ``*`` and ``?`` wildcards.
If PATTERN is a simple string without wildcards, then names containing this string will be considered.
EOF
);

my $fnret;

$fnret = OVH::Bastion::get_group_list();
$fnret or osh_exit $fnret;

my $includere = OVH::Bastion::build_re_from_wildcards(wildcards => \@includes, implicit_contains => 1)->value;
my $excludere = OVH::Bastion::build_re_from_wildcards(wildcards => \@excludes, implicit_contains => 1)->value;

my $result_hash = {};
foreach my $name (sort keys %{$fnret->value}) {

    # if we have excludes, match name against the built regex
    next if ($excludere && $name =~ $excludere);

    # same for includes
    next if ($includere && $name !~ $includere);

    my @flags;
    push @flags, 'owner'      if OVH::Bastion::is_group_owner(group => $name);
    push @flags, 'gatekeeper' if OVH::Bastion::is_group_gatekeeper(group => $name);
    push @flags, 'aclkeeper'  if OVH::Bastion::is_group_aclkeeper(group => $name);
    push @flags, 'member'     if OVH::Bastion::is_group_member(group => $name);
    push @flags, 'guest'      if OVH::Bastion::is_group_guest(group => $name);
    if (@flags or $all) {
        push @flags, 'no-access' if not @flags;
        my $line = sprintf "%18s", $name;
        $line .= sprintf " %14s", colored(grep({ $_ eq 'owner' } @flags)      ? 'Owner'      : '-', 'red');
        $line .= sprintf " %19s", colored(grep({ $_ eq 'gatekeeper' } @flags) ? 'GateKeeper' : '-', 'yellow');
        $line .= sprintf " %18s", colored(grep({ $_ eq 'aclkeeper' } @flags)  ? 'ACLKeeper'  : '-', 'magenta');
        $line .= sprintf " %15s", colored(grep({ $_ eq 'member' } @flags)     ? 'Member'     : '-', 'green');
        $line .= sprintf " %14s", colored(grep({ $_ eq 'guest' } @flags)      ? 'Guest'      : '-', 'cyan');
        osh_info $line;
        $result_hash->{$name} = {flags => \@flags};
    }
}
if (keys %$result_hash) {
    osh_info "\nIf you want to see all the groups, even the ones you don't have access to, use --all" if not $all;
}
else {
    if (not $all) {
        osh_ok R('OK_EMPTY', msg => "You are not in any group yet! You can use --all to see all groups");
    }
    else {
        osh_ok R('OK_EMPTY', msg => "No group has been created on this bastion yet!");
    }
}
osh_ok $result_hash;
