#!/usr/bin/perl
# check the status of all the files recursively from current directory
# accepts options
#     -v:  to include listing up-to-date files, default up-to-date
#          files are not listed.
#     -r:  compare with version, default is current version
#     -d:  host where the repository resides 
# two levels of check: consistancy:      Missing and New
#                      modified status:  Modified, Uptodate, Added and Removed
#
# Added features:
#     list the subdirectory only if the whole subdirectory is new
#
# Do not handle merging info yet.
#
# Version 0.2, Feb 2, 99
# Min Xu
# Physics Dept., CCNY, USA
# minxu@sci.ccny.cuny.edu
# 
require "prcs-parse.pl";
use GDBM_File;
use Getopt::Std;
getopts('vr:d:');

die "No project file present" unless ($project, $version)=&get_default_project; 
$db=".".$project.".md5";
$aux=".".$project.".prcs_aux";
if ($opt_r) { $ver_from=$opt_r; }
else { $ver_from=$version; }
print "Changes made from version ", $ver_from, " to ", $version, "(w):\n";

# find the directories not in the project
%present_directories=();
open(DIRS, "find . -type d -maxdepth 1 -mindepth 1 |") || die ("find failed");
while (<DIRS>) {
  chop;
  $present_directories{substr($_, 2)}=1;  # get rid of the leading "./"
}
close(DIRS);
open(DIRS, "prcs execute -q --match :implicit-directory|") || die ("prcs failed");
while (<DIRS>) {
  chop;
  delete($present_directories{$_});
}
close(DIRS);
foreach $key (sort keys %present_directories) {
  printf "%-40s%s", $key, "New Directory\n";
}

# get all files listed in the directory recursively excluding the new directories
%present_files=();
open(FILES, "find . -type f -print|") || die ("find failed");
FILE: while (<FILES>) {
  chop;
  $_=substr($_, 2); # get rid of the leading "./"
  foreach $key (keys %present_directories) {
    next FILE if /^$key\//;
  }
  $present_files{$_}=1  
}
close(FILES);
delete $present_files{$project . ".prj"};
delete $present_files{$aux};
delete $present_files{$db};
delete $present_files{$db.".db"};

# get all files and their md5sums in the project_from
if ( $opt_d ) {
  %md5_from=&remote_md5sum_hash($opt_d, $project, $ver_from); }
else {
  %md5_from=&md5sum_hash($project, $ver_from); }

# generate md5sums for all files in the working project and report missing files
$dbtime=0 unless $dbtime=(stat($db))[10]; # undefined if no $db file
dbmopen %md5_work, $db, 0640;
open(WORK, "prcs execute -q --not :.*directory ./ |") || die ("prcs failed");
while (<WORK>) {
  chop;
  next if /$project.prj/;
  if (/$db/ || /$aux/) {
    print "Warning: $_ should not be included in the .prj file!\n";
    next;
  }
  $file=$_;
  delete $present_files{$file};
  if (! -f $file) {
    printf "%-40s%s", $_, "Missing!\n";
    delete $md5_work{$file};
    delete $md5_from{$file};
  }
  elsif ( $dbtime < (stat($file))[10] ) {
    $md5_work{$file}=&gen_md5_for_a_file($file);
  }
}
close(WORK);

# I do not know why a null key inside it, need to delete it.
foreach $key (keys %md5_work) {
  delete $md5_work{$key} unless $key; 
}

# report new files
foreach $key (sort keys %present_files) {
  printf "%-40s%s", $key, "New\n";
}

# report up-to-date, modified or removed
&compare(\%md5_from, \%md5_work, $opt_v);
dbmclose %md5_work;
