#!/usr/bin/perl -w

use strict;
use warnings;

use File::Basename;
use ALTLinux::RepoList;
use ALTLinux::RepoList::CLI 0.002 qw/$arch_allow_all %arch_to_use/;
use Source::Shared::CLI;
#our @ISA = qw/Source::Shared::CLI/;
our @ISA = qw/ALTLinux::RepoList::CLI/;
;

my $verbose=0;
$verbose=1 if $ENV{TERM}; # not to pollute cron mail

sub cli_container_ref {
    return ['ALTLinux::RepoList::CLI'];
}

# ------------------------------------------------------------

my $out_bin_names= $0 =~ /-to-bin-names$/;
my $out_bin_files= $0 =~ /-to-bin-files$/;
my $out_src_names= $0 =~ /-to-src-names$/;
my $out_src_files= $0 =~ /-to-src-files$/;
my $in_bin_names= $0 =~ /-bin-names-to-/;
my $in_bin_files= $0 =~ /-bin-files-to-/;
my $in_src_names= $0 =~ /-src-names-to-/;
my $in_src_files= $0 =~ /-src-files-to-/;

$ALTLinux::RepoList::CLI::need_bin=1 if $in_bin_names or $in_bin_files or $out_bin_names or $out_bin_files;
$ALTLinux::RepoList::CLI::need_src=1 if $in_src_names or $in_src_files or $out_src_names or $out_src_files;

my $self=__PACKAGE__->new();
$self->get_and_process_cli_options();
$self->verify_args();


my (%srcname2srpm,%srpm2srpmprefix,%srpm2srcname);
if ($ALTLinux::RepoList::CLI::need_src) {
    &ALTLinux::RepoList::process_src_lists(
	 sub {
	     my ($name,$evr,$srpm,$reporoot)=@_;
	     $srcname2srpm{$name}=$srpm;
	     $srpm2srcname{$srpm}=$name;
	     $srpm2srpmprefix{$srpm}=$reporoot.'/files/SRPMS/';
	 },
	 @ALTLinux::RepoList::CLI::srclists
	);
}
my (%binnamearch2rpm,%rpm2rpmprefix,%rpm2binname,%rpm2srpm,%srpm2rpm);
if ($ALTLinux::RepoList::CLI::need_bin) {
    &ALTLinux::RepoList::process_bin_lists(
	 sub {
	     my ($name,$evr,$arch,$rpm,$srpm,$reporoot)=@_;
	     return if !$arch_allow_all and !$arch_to_use{$arch};
	     $binnamearch2rpm{$name}->{$arch}=$rpm;
	     $rpm2binname{$rpm}=$name;
	     $rpm2srpm{$rpm}=$srpm;
	     push @{$srpm2rpm{$srpm}},$rpm;
	     $rpm2rpmprefix{$rpm}=$reporoot.'/files/'.$arch.'/RPMS/';
	 },
	 @ALTLinux::RepoList::CLI::binlists
	);
}

my (@src_missing,@bin_missing);
sub __srcname2srpm {
    my $srcname=shift;
    my $srpm=$srcname2srpm{$srcname};
    if (!defined($srpm)) {
	push @src_missing, $srcname;
	return;
    } else {
	return $srpm;
    }
}
sub __srcfile2srpm {
    return basename(shift);
}
sub __binfile2rpm {
    return basename(shift);
}
sub __binname2rpm {
    my $binname=shift;
    my $_arches=$binnamearch2rpm{$binname};
    my @rpms;
    if ($_arches) {
	foreach my $arch (keys %$_arches) {
	    push @rpms,$_arches->{$arch};
	}
    } else {
	push @bin_missing, $binname;
    }
    return @rpms;
}
sub __binname2srpm {
    my $binname=shift;
    my $_arches=$binnamearch2rpm{$binname};
    my @rpms;
    if ($_arches) {
	foreach my $arch (keys %$_arches) {
	    push @rpms,$_arches->{$arch};
	}
    } else {
	push @bin_missing, $binname;
    }
    my %srpms= map {$_=>1} map {&__rpm2srpm($_)} @rpms;
    #warn 'DEBUG: rpms=',join(':',@rpms),' srpms=',join(':',keys(%srpms));
    return keys(%srpms);
}
sub __srpm2rpm {
    my $srpm=shift;
    my $_srpm=$srpm2rpm{$srpm};
    if (!$_srpm) {
	push @bin_missing, $srpm;
	return;
    }
    return @$_srpm;
}
sub __rpm2srpm {
    my $rpm=shift;
    my $srpm=$rpm2srpm{$rpm};
    if (!defined($srpm)) {
	push @src_missing, $rpm;
	return;
    }
    return $srpm;
}
sub __rpm2rpmpath {
    my $rpm=shift;
    my $rpmprefix=$rpm2rpmprefix{$rpm};
    unless (defined($rpmprefix)) {
	warn "Bad list: NOT defined rpmprefix for ",$rpm;
	return;
    }
    return $rpmprefix.$rpm;
}
sub __srpm2srpmpath {
    my $srpm=shift;
    my $srpmprefix=$srpm2srpmprefix{$srpm};
    unless (defined($srpmprefix)) {
	warn "Bad list: NOT defined srpmprefix for ",$srpm;
	return;
    }
    return $srpmprefix.$srpm;
}
sub __rpm2binname {
    return map {$rpm2binname{$_}} @_;
}
sub __srpm2srcname {
    return map {$srpm2srcname{$_}} @_;
}

my @process_input_map_chain;
if ($in_src_names) {
    push @process_input_map_chain, \&__srcname2srpm;
    push @process_input_map_chain, \&__srpm2rpm if ($out_bin_names or $out_bin_files);
} elsif ($in_src_files) {
    push @process_input_map_chain, \&__srcfile2srpm;
    push @process_input_map_chain, \&__srpm2rpm if ($out_bin_names or $out_bin_files);
} elsif ($in_bin_names) {
    if ($out_src_names or $out_src_files) {
	push @process_input_map_chain, \&__binname2srpm;
    } else {
	push @process_input_map_chain, \&__binname2rpm;
    }
} elsif ($in_bin_files) {
    push @process_input_map_chain, \&__binfile2rpm;
    push @process_input_map_chain, \&__rpm2srpm if ($out_src_names or $out_src_files);
}

if ($out_src_names) {
    push @process_input_map_chain, \&__srpm2srcname;
} elsif ($out_src_files) {
    push @process_input_map_chain, \&__srpm2srpmpath;
} elsif ($out_bin_names) {
    push @process_input_map_chain, \&__rpm2binname;
} elsif ($out_bin_files) {
    push @process_input_map_chain, \&__rpm2rpmpath;
}

$self->process_args(\@process_input_map_chain);

warn "WARNING: src names not found: ", join(' ',@src_missing),"\n" if @src_missing;
warn "WARNING: bin names not found: ", join(' ',@bin_missing),"\n" if @bin_missing;
# ------------------------------------------------------------
