#!/usr/bin/perl

sub pkgbase {
  my $pkg=shift;
  my $i;
  if(($i=rindex($pkg,"/"))>=0) {
    $pkg=substr($pkg,$i+1);
  }
  $pkg=~s/\.t[gblx]z$//;
  return($pkg);
}

sub dir_name {
  my $pkg=shift;
  my $i;
  if(($i=rindex($pkg,"/"))>=0) {
    $pkg=substr($pkg,0,$i);
  }
  else {
    $pkg=undef;
  }
  return($pkg);
}


sub package_name {
  my $pkg=shift;
  my $pkgn;
  $_=pkgbase($pkg);
  ($pkgn)=m/(.+)-.+?-.+?-.+?/;
  if(length($pkgn)==0) { $pkgn=$_; }
  return($pkgn);
}

sub package_ver {
  my $pkg=shift;
  my ($pkgv,$build);
  $_=pkgbase($pkg);
  ($pkgv,$build)=m/.+-(.+?)-.+?-(\S+)/;
  if(length($pkgv)==0) { $pkgv=$_; }
  else { $pkgv.=".$build"; }
  return($pkgv);
}

sub sspkg {
  my($max,@av,@bv,$i,$aa,$anum,$aalpha,$ba,$bunm,$balpha);
  # 2022-01-10: Reverting order (swapping $a/$b on first 3 lines)
  if(package_name($a) ne package_name($b)) { return(pkgbase($b) cmp pkgbase($a)); }
  @av=split(/[\._]/,package_ver($b));
  @bv=split(/[\._]/,package_ver($a));
  $max=$#av;
  if($#bv>$max) { $max=$#bv; }
  $ret=0;
  for($i=0;$i<=$max;$i++)
  {
    $_=$av[$i];
    ($aa,$anum,$aalpha)=m/(\D*)(\d*)(.*)/;
    $_=$bv[$i];
    ($ba,$bnum,$balpha)=m/(\D*)(\d*)(.*)/;
#    print "a$i a=$aa, num=$anum, alpha=$aalpha\n";
#    print "b$i a=$ba, num=$bnum, alpha=$balpha\n";
    if($aa gt $ba) { return(1); }
    elsif($aa lt $ba) { return(-1); }
    if($anum > $bnum) { return(1); }
    elsif($anum < $bnum) { return(-1); }
    if($aalpha gt $balpha) { return(1); }
    elsif($aalpha lt $balpha) { return(-1); }
  }
  return(0);
}

if(length($ARGV[0])>0) {
  my $filedir=shift;
  if(open(C,$filedir)) {
     while(<C>)
     {
       chop;
       ($slack64,$dir,$pkg)=m| (\./slackware64/)(\S+?)/(\S+\.t.z)$|;
       if(length($pkg)>0) {
         $dir{package_name($pkg)}=$dir;
       }
     }
     close(C)
  }
}

sub CheckFiles
{
  my $file=shift;
  my $base=$file;
  my $all=$file;
  $base=~s/\.t.z$//;
  if(-f "$base.txt" || -l "$base.txt") {
    $all.=" $base.txt";
  }
  if(-f "$file.asc" || -l "$file.asc") {
    $all.=" $file.asc";
  }
  return($all);
}

$pwd=`pwd`;
print "Reading list... $pwd";

while(<STDIN>)
{
  chop;
  # Remove "old_packages" from the next regular expression if you think some packages get wrongly moved into "old_packages" dir
  if(m/^old_packages|^temp|^patches|^testing|^pasture|^extra.llvm|^extra.rust|kernel-modules|^extra.xf86-video-fbdev|gcc-.*7\.5\.|make.*guile|^extra.samba/) { next; }
  if(-l $_ ) { 
    $l=readlink($_);
    unless($l=~m/commonpkgs/) { 
      #print "Skipping $_\n"; 
      next;
    }
  }
  push(@pkg,$_);
}

#@pkg = sort sspkg @pkg; # sort by time

for($i=0;$i<=$#pkg;$i++)
{
  $pkg = package_name($pkg[$i]);
  $dir = dir_name($pkg[$i]);
  #print "== $pkg[$i] ".package_ver($pkg[$i])."\n";
  if(defined($pkg{$pkg})) {
    if($pkg[$i]=~m/^old_packages/) { next; }
    if($count{$pkg}<1) {
      print "- keeping $pkg{$pkg} (moving $pkg[$i])\n";
    }
    else {
      print("mv -i $pkg[$i]\n");
    }
    $count{$pkg}++;
    $pkgs=CheckFiles($pkg[$i]);
    system("mkdir -p old_packages/ ; mv -i $pkgs old_packages/");
  }
  else {
    if(defined($dir{$pkg}) && defined($dir) && $dir{$pkg} ne $dir) {
      print "** WRONG DIR, moving $pkg[$i] to $dir{$pkg}\n";
      $pkgs=CheckFiles($pkg[$i]);
      system("mv -i $pkgs $dir{$pkg}/");
      $pkg[$i]=$dir{$pkg}."/".substr($pkg[$i],rindex($pkg[$i],"/")+1);
    }
    $pkg{$pkg}=$pkg[$i];
  }
}
