#! /usr/bin/perl -w
#                              -*- Mode: Perl -*- 
# Debian-pkg.pm --- 
# Author           : Manoj Srivastava ( srivasta@tiamat.datasync.com ) 
# Created On       : Wed Jan 22 09:53:33 1997
# Created On Node  : tiamat.datasync.com
# Last Modified By : Manoj Srivastava
# Last Modified On : Mon Mar  9 02:37:53 1998
# Last Machine Used: tiamat.datasync.com
# Update Count     : 272
# Status           : Unknown, Use with caution!
# HISTORY          : 
# Description      : 
# 
# 


use strict;
use Carp;
require 5.001;

use Debian::Package::Dependency_List;
use Debian::Package::Package;
use Debian::Package::List;
use Getopt::Long;

package main;
    
sub main {
  my $installed;
  my $candidates;
  my $ret;
  my $do_depends = 1;
  my $strict_depends = 1;
  my $do_order = 1;
  my $recommends = 0;
  my $suggests = 0;
  my $consistent = 1;
  my $print_failures = 1;
  my $print_found = 0;
  my $filename;
  my $status = 't/Status';
  my $usage;
  my $MYNAME;
  
  ($MYNAME     = $0) =~ s|.*/||;


  $filename = "t/Packages";
  die "Could not find new Packages file $filename" unless
    -f $filename;

  ######################################################################
  #                     Phase One: Gather data                         #
  ######################################################################

  # Installed file (default value, taken from status file)
  if ($do_depends) {
    $installed = Debian::Package::Installed->new('filename' => $status);
  }
  # The new candidates (taken from the packages file)
  $candidates = Debian::Package::New->new('filename' => $filename);

  ######################################################################
  #                 Phase Two: Check dependencies                      #
  ######################################################################

  # Omit phase Two and Three unless $do_depends is TRUE
  if ($do_depends) {
    # This sets Types which will show up as critical errors. Does not
    # change what errors are recorded. 
    $candidates->set_fatal_failure_on_types('Type List' =>
					    "Pre-Depends Depends Conflict");
    
    # Check Pre-Dependencies
    $candidates->check_relations('Consistent' => $consistent,
				 'Installed' => $installed,
				 'Field' => 'Pre-Depends');
    # Check Dependencies
    $candidates->check_relations('Consistent' => $consistent,
				 'Installed' => $installed,
				 'Field' => 'Depends');
    # Check Conflicts
    $candidates->check_relations('Consistent' => $consistent,
				 'Installed' => $installed,
				 'Field' => 'Conflicts');
    # Check Recommendations
    $candidates->check_relations('Consistent' => $consistent,
				 'Installed' => $installed,
				 'Warn'       => 'True',
				 'Field' => 'Recommendations')
      if $recommends;
    # Check Suggestions
    $candidates->check_relations('Consistent' => $consistent,
				 'Installed'  => $installed,
				 'Warn'       => 'True',
				 'Field'      => 'Suggestions')
      if $suggests;
    
  ######################################################################
  #      	      Phase Three: Print Results                       #
  ######################################################################
    if ($print_failures) {
      my $result_string = 
	$candidates->result_as_string('Type' => 'All',
				      'Category' => 'Failed');
      if ($result_string) {
	print  "=" x70, "\n";
	print  "Failed:\n";
	print "$result_string";
	print  "=" x70, "\n";
      }

      my $unknowns = 
	$candidates->result_as_string('Type' => 'All',
				      'Category' => 'Unknown');
      if ($unknowns) {
	print  "=" x70, "\n";
	print  "Unknown:\n";
	print "$unknowns";
	print  "=" x70, "\n";
      }

      # Different from above to see an example of print result
      my $numconflicts = 
	$candidates->check_result('Type' => 'All',
				  'Category' => 'Conflict');
      if ($numconflicts > 0) {
	print  "=" x70, "\n";
	print  "Conflicted:\n";
	my $result_string = 
	  $candidates->result_as_string('Type' => 'All',
					'Category' => 'Conflict');
	print "$result_string";
	print  "=" x70, "\n";
      }
    }
    
    if ($print_found) {
      my $result_string = 
	$candidates->result_as_string('Type' => 'All',
				      'Category' => 'Found');
      if ($result_string) {
	print  "=" x70, "\n";
	print  "Found:\n";
	print "$result_string";
	print  "=" x70, "\n";
      }
    }
    if ($strict_depends) {
      my $critical_errors = 
	$candidates->check_result('Type' => "Critical",
				  'Category' => 'Failed') 
	  + $candidates->check_result('Type' => "Critical",
				      'Category' => 'Conflict') 
	  + $candidates->check_result('Type' => "Critical",
				      'Category' => 'Unknown');
      if ($critical_errors > 0) {
	print "$critical_errors Critical errors encountered. Exiting.\n";
	exit ($critical_errors);
      }
    }
  }
  
  ######################################################################
  #                Phase Four: Gather ordering data                    #
  ######################################################################
  
  return 0 unless $do_order;

  # Order Pre-Dependencies
  $candidates->order('Field' => 'Pre-Depends');
  # Order Dependencies
  $candidates->order('Field' => 'Depends');

  ######################################################################
  #                    Phase Five: Do ordering                         #
  ######################################################################
  
  # Get ordering info and do topological sorting
  my $order_string = $candidates->get_ordering();
  # This is the raw order string
  print "$order_string";
  return;
  

  # Not reached.
  print "No packages to order. Exiting.\n" unless $order_string;
  return 2 unless $order_string;
  
  # This is the first method used to insert Breaks
  my $order_one = 
    $candidates->insert_breaks('Ordered List' => $order_string);
  print "$order_one\n";

  my %force_options = $candidates->list_marks("Mark" => '\-\-');
  my $forced_pkg;
  
  foreach $forced_pkg (keys %force_options) {
    my $option;
    my @options = split ' ', $force_options{$forced_pkg};
    for $option (@options) {
      next unless $option =~ /\-\-/o;
      
      print "Package $forced_pkg will need $option for installation)\n";
    }
  }

  # This is another way to insert breaks
  # print "=" x 70;
  # my $order_two = 
  #  $candidates->{' _Targets'}->insert_breaks('Ordered List' => $order_string);
  # print "$order_two\n";
}


&main::main();

    
