package AllBin;
use warnings;
use strict;
use integer;
use AllSrcBin;
our @ISA = ( 'AllSrcBin' );
use CheckVer;
use DebSrcBin;
use AllProv;
use DebSrc;
use DebBin;
use AllSrc;

our $pri_min_default = 10;

# List the various conflict fields.
our %dep_cfl = map {
  map { $_->{xkey} => 1 } @{ $_->{xkeys} }
} grep { !$_->{sense} } @DebBin::dep_class;

sub new {
  my $class = shift;
  my $bin   = AllSrcBin::new( 'AllBin', @_ );
  bless $bin, $class;
  return $bin;
}

sub instantiate_one {
  my( $bin, $fh ) = @_;
  return DebBin->new( $fh );
}

# Add the various build-dependency fields to the binaries.
sub add_build_dep {
  my( $bin, $src ) = @_;
  for my $pname ( grep {length} keys %$bin ) {
    my $bin1  = $bin ->{$pname};
    my $sname = $bin1->{Source};
    my $src1  = $src ->{$sname};
    for my $dkey ( @DebSrc::dkey_subparsable_bdep ) {
      my $xkey = "x$dkey";
      $bin1->{$xkey}
        and die "$0: build-dependencies in the Packages file? $pname\n";
      $src1->{$xkey} or next;
      $bin1->{$xkey} = $src1->{$xkey};
    }
  }
  return $bin;
}

# Reverse package enhancements.
sub reverse_enhance {
  my $bin  = shift;
  my $prov = $bin->{''}
    or die "$0: AllBin fails to refer to AllProv\n";
  $bin->{$_}{renh} = [] for ( grep {length} keys %$bin );
  for my $pname ( sort grep {length} keys %$bin ) {
    my $bin1 = $bin->{$pname};
    for my $enh1 ( map {@$_} @{ $bin1->{xEnhances} } ) {
      push @{ $bin->{$_}{renh} }, [
        {
          vname => $pname,
          rel   => '=',
          ver   => $bin1->{Version},
        }
      ] for $prov->pnames_provided(
        $enh1->{vname}, $enh1->{rel}, $enh1->{ver}
      );
    }
  }
  return $bin;
}

# Select all packages meeting a minimum priority level.  (This method is not
# called automatically in any of the basic instantiations, but it is provided
# for the user's convenience.)
sub select_by_pri {
  my( $bin, $pri, $sel ) = @_;
  defined $pri or $pri = $pri_min_default;
  defined $sel or $sel = $DebSrcBin::select_up_default;
  for my $pname ( grep {length} keys %$bin ) {
    my $bin1        = $bin->{$pname};
    $bin1->{select} = $sel
      if $bin1->{select} < $sel && $bin1->{pri} >= $pri;
  }
  return $bin;
}

# Return selected pnames whose dependencies the other selections do not
# satisfy.  Indicate full satisfaction by returning the empty list.
sub are_selections_consistent {
  my( $bin, $levels, $sel ) = @_;
  my $prov = $bin->{''}
    or die "$0: AllBin fails to refer to AllProv\n";
  defined $sel or $sel = $DebSrcBin::select_up_default;
  map {
    $bin->{$_}->are_all_deps_satisfied( $prov, $levels, $sel );
  } grep { $bin->{$_}{select} >= $sel } sort grep {length} keys %$bin;
}

1;

