#!/usr/bin/perl -w

use strict;
use warnings;

use File::Path qw/make_path remove_tree/;
use File::Basename;
use Getopt::Long;
use ALTLinux::ACL;
use Data::Array2ArrayMap::Hash::XSTree;

my $reportdir='.';
my ($acldir,$leaderdir,$expandedacldir,$expandedleaderdir);
my $nvr_mode;

my ($by_name,$by_leader,$by_acl,$by_expanded_leader,$by_expanded_acl)=(0,1,1,1,1);
my $result = GetOptions (
    @ALTLinux::ACL::LONGOPT,
    'dest-dir|destdir=s' => \$reportdir,
    'exact-acl-dir|acl-dir|acldir=s' => \$acldir,
    'exact-leader-dir|leader-dir|leaderdir=s' => \$leaderdir,
    'expanded-acl-dir=s' => \$expandedacldir,
    'expanded-leader-dir=s' => \$expandedleaderdir,
    'by-acl!'  => \$by_acl,
    'by-leader!'  => \$by_leader,
    'by-expanded-acl!'  => \$by_expanded_acl,
    'by-expanded-leader!'  => \$by_expanded_leader,
    'by-name!'  => \$by_name,
    "nvr"  => \$nvr_mode,
);
$acldir||=$reportdir.'/'.'by-acl';
$expandedacldir||=$reportdir.'/'.'by-expanded-acl';
$leaderdir||=$reportdir.'/'.'by-leader';
$expandedleaderdir||=$reportdir.'/'.'by-expanded-leader';

my $BY_ACL=Data::Array2ArrayMap::Hash::XSTree->new();
my $BY_LEADER=Data::Array2ArrayMap::Hash::XSTree->new();
my $BY_EXPANDED_ACL=Data::Array2ArrayMap::Hash::XSTree->new();
my $BY_EXPANDED_LEADER=Data::Array2ArrayMap::Hash::XSTree->new();

my $aclmap=ALTLinux::ACL->new();

while (<>) {
    next if /^\s*$/;
    chomp;
    my ($name,$altver,$extver,$url)=split("\t");
    $name=basename($name);
    $name=~s/-[^-]+-[^-]+$// if $nvr_mode;
    my $pkgkey="$name\t$altver";
    my $extkey="$extver\t$url";
    my @acls=$aclmap->acl($name);
    my $leader=$acls[0];
    foreach my $acl (@acls) {
	$BY_ACL->append([$acl,$pkgkey],[$extkey]);
    }
    $BY_LEADER->append([$leader,$pkgkey],[$extkey]);
    if ($by_expanded_leader) {
	my @eleaders=(not $aclmap->is_group($leader)) ? $leader: $aclmap->group_acl($leader);
	foreach my $eleader (@eleaders) {
	    $BY_EXPANDED_LEADER->append([$eleader,$pkgkey],[$extkey]);
	}
    }
    if ($by_expanded_acl) {
	foreach my $acl ($aclmap->acl_with_groups_expanded($name)) {
	    $BY_EXPANDED_ACL->append([$acl,$pkgkey],[$extkey]);
	}
    }
}

if ($by_acl) {
    &__triplet_by_1($BY_ACL,$acldir);
}

if ($by_leader) {
    &__triplet_by_1($BY_LEADER,$leaderdir);
}

if ($by_expanded_acl) {
    &__triplet_by_1($BY_EXPANDED_ACL,$expandedacldir);
}

if ($by_expanded_leader) {
    &__triplet_by_1($BY_EXPANDED_LEADER,$expandedleaderdir);
}

sub __triplet_by_1 {
    my ($KEYSTORE,$dir)=@_;
    &prepare_report_subdir($dir);
    foreach my $person (sort $KEYSTORE->keys_at([])) {
	open (CURFILE, ">", "$dir/$person.txt");
	my @rpms = sort $KEYSTORE->keys_at([$person]);
	foreach my $rpm (@rpms) {
	    my @extlist=sort $KEYSTORE->get([$person,$rpm]);
	    foreach my $ext (@extlist) {
		print CURFILE "$rpm\t$ext\n";
	    }
	}
	close (CURFILE);
    }
}

sub prepare_report_subdir {
    my ($dir)=@_;
    remove_tree($dir);
    make_path($dir);
}

=head1	NAME

altlinux-acl-report-split-by-acl - group text database rows by leader or acl.

=head1	SYNOPSIS

B<altlinux-acl-report-split-by-acl>
[B<--destdir> I<path to destdir>]
[B<--acl-dir> I<name>]
[B<--leader-dir> I<name>]
[B<--expanded-acl-dir> I<name>]
[B<--expanded-leader-dir> I<name>]
[B<--by-acl,--no-by-acl>]
[B<--by-leader,--no-by-leader>]
[B<--by-expanded-acl,--no-by-expanded-acl>]
[B<--by-expanded-leader,--no-by-expanded-leader>]
[B<--by-name,--no-by-name>]
[B<--nvr>]
I<input text file>

=head1	DESCRIPTION

B<altlinux-acl-report-split-by-acl> groups the rows of database text file
that have a column with a src.rpm name by acl leader or acl name
and outputs the grouped subsets of input rows in I<destdir/by-acl>
and/or I<destdir/by-leader> folders.

=head1	OPTIONS

=over

=item	B<--destdir> I<path>

Destination dir to create reports.

=item	B<--acl-dir> I<name>

Name of acldir. Default is by-acl.

=item	B<--leader-dir> I<name>

Name of leaderdir. Default is by-leader.

=item	B<--expanded-acl-dir> I<name>

Name of dir for reports grouped by expanded acl. Default is by-expanded-acl.

=item	B<--expanded-leader-dir> I<name>

Name of dir for reports grouped by expanded leader. Default is by-expanded-leader.

=item	B<--by-acl>, B<--no-by-acl>

Group by acl. Default.

=item	B<--by-leader>, B<--no-by-leader>

Group by leader. Default.

=item	B<--by-expanded-acl>, B<--no-expanded-by-acl>

Group by acl (groups expanded). Default.

=item	B<--by-expanded-leader>, B<--no-by-expanded-leader>

Group by leader (groups expanded). Default.

=item	B<--by-name>, B<--no-by-name>

Group by name. Disabled by default.

=item	B<--acl-branch> I<sisyphus|t7|...>

Name of branch. Default is sisyphus.

=item	B<--acl-expire> I<days>

Cache expiration time, in days (float point value). Default is 1/5 day.

=item	B<--acl-verbose> I<verbosity level>

Internal debug/verbosity for ALTLinux::ACL.

=item	B<--nvr>

NVR mode. In this mode, the input is not a srpm name, but
is expected to look like name-version-release.something,
like foo-1.0-alt1, foo-1.0-alt1.log, foo-1.0-alt1.noarch,
foo-1.0-alt1.noarch.patch.

=back

=head1	AUTHOR

Written by Igor Vlasenko <viy@altlinux.org>.

=head1	COPYING

Copyright (c) 2012-2023 Igor Vlasenko, ALT Linux Team.

This is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.

=cut
