#! /bin/perl

sub array_eq
{

  my $aref = shift;

  my $bref = shift;

  if (@$aref != @$bref)
  {
     return 0
  }
 
  # compare size

  for my $i (0..$#$aref)
  {
     #
     # compare values
     #
     return 0 unless $$aref[$i] eq $$bref[$i];
  }

  return 1;
}

sub build_string
{

  my $array = shift;

  my $start_index = shift;

  my $separator = shift;

  $array_size = @$array;

  $built_string = "";
 
  print "passed in array".$array[$start_index]."\n";

  while ($start_index < $array_size +1)
  {
     $built_string = $built_string.$array[$start_index];

     $start_index = $start_index + 1;
  }

  return $built_string;
}
#
# Read the list of drives to go through
#

$num_args = @ARGV;

$DRIVE_LIST_FILE = "DriveList.txt";

open DRIVE_LIST_FILE, $DRIVE_LIST_FILE or die "Cannot open drive list file\n";

@DriveList = (<DRIVE_LIST_FILE>);

$DriveListSize = scalar(@DriveList);

close DRIVE_LIST_FILE;

$DriveIndex = 0;
$FileCount = 0;
$DirectoryCount = 0;

#
# Create the duplicate file list file
#

($Seconds,$Minutes,$Hours,$Day,$Month,$Year) = (localtime)[0,1,2,3,4,5];
$Year = $Year + 1900;

$Date = sprintf("%02d",$Month)."-";
$Date = $Date.sprintf("%02d",$Day)."-";
$Date = $Date.sprintf("%04d",$Year)."-";
$Date = $Date.sprintf("%02d",$Hours)."_";
$Date = $Date.sprintf("%02d",$Minutes)."_";
$Date = $Date.sprintf("%02d",$Seconds);

$DuplicateFileName = "Duplicate_File_List_".$Date;
#print $DuplicateFileName."\n";

$OpenStatus = 1;
 
open DUPLICATE_FILE_NAME, ">".$DuplicateFileName or $OpenStatus = 0;
if ($OpenStatus == 0)
{
   print "$!";
   print " ";
   die "Unable to open duplicate file name file\n";
}
#
# Create the open failed file list file
#
$OpenFailedFileName = "Open_Failed_File_List_".$Date;
#print $OpenFailedFileName."\n";

open OPEN_FAILED_FILE_NAME, ">".$OpenFailedFileName or die "Unable to open open failed file name file\n";

#
# Loop through each drive to get a list of files
#
while ($DriveIndex < $DriveListSize)
{
    $CurrentDrive = @DriveList[$DriveIndex];

    chomp $CurrentDrive;

    $DirCommand ="dir ".$CurrentDrive.":\\ /S";

    # print $DirCommand."\n";

    #
    # Obtain the list of files in the drive
    #
    @DriveFileList = `$DirCommand`;

    print "Directory done\n";

    #
    # Now append the files to the file list
    #
    foreach $FileName (@DriveFileList)
    {
        chomp $FileName;

        #print $FileName."\n";

        @ParsedLine = split /\s+/,$FileName;
       
        # shift @parse_line;

        $LineSize = scalar(@ParsedLine);    

        if ($LineSize > 0)
        {
            #print $ParsedLine[0]."\n";
            #print $LineSize."\n";

            #
            # Determine if this is a directory and if so add it to the
            # directory array and increment the index
            #
            if ($ParsedLine[1] eq "Directory")
            {
                print "Directory is ".$ParsedLine[3]."\n";
                #
                # We have a new directory - make sure we have all of it in case there 
                # are spaces 
                $Directory = build_string(\@ParsedLine,3,"\\");

                #
                # Now add it to the list
                #
                $DirectoryList[$DirectoryCount] = $Directory."\\";
                # chomp $DirectoryList[$DirectoryCount];
                print "Adding directory ".$DirectoryList[$DirectoryCount]."\n";
                $DirectoryCount =$DirectoryCount + 1;
            }

            if ($LineSize == 5 &&
                $ParsedLine[3] ne "<DIR>" &&
                $ParsedLine[2] ne "File(s)")
            {
                #
                # This is a file to add to the list
                #
                $ActualFiles[$FileCount] = build_string(\@ParsedLine,4,"");
                # chomp $ActualFiles[$FileCount];
                $FileDirectory[$FileCount]= $DirectoryCount;
                print "Adding file ".$ActualFiles[$FileCount]."\n";
                print "Adding Bytes ".$ParsedLine[3]."\n";
                $FileSize[$FileCount] = $ParsedLine[3];
 
                #
                # File is not deleted yet
                #
                $FileDeleted[$FileCount] = 0;
                $ByteCount = $ByteCount + $ParsedLine[3];
                $FileCount = $FileCount + 1;
            } 
        }
    }

    #
    # Point to the next drive
    #
    $DriveIndex = $DriveIndex + 1;
}

#$FileCount = scalar(@ActualFiles);    
#$DirectoryCount = scalar(@DirectoryList);

# 
# Loop through the list of files
#
$PrimaryFileIndex = 0;

$OpenFailCount = 0;
$CompareCount = 0;

while ($PrimaryFileIndex < $FileCount)
{ 
 
   $PrimaryFile = $DirectoryList[$FileDirectory[$PrimaryFileIndex] - 1].$ActualFiles[$PrimaryFileIndex];
   #$PrimaryFile = $DirectoryList[$FileDirectory[$PrimaryFileIndex]].$ActualFiles[$PrimaryFileIndex];
   print "Primary file #".$PrimaryFileIndex." ".$PrimaryFile."\n";
   
   $FileRead = 0;
   
   #
   # Has the file been deleted
   #
   if ($FileDeleted[$PrimaryFileIndex] == 0)
   {
      $OpenStatus = 1;

      open PRIMARY_FILE, $PrimaryFile or $OpenStatus = 0;
      if ($OpenStatus == 0)
      {
         $ErrorMessage = "Cannot open primary file ".$PrimaryFile." - ".$!."\n";
         print $ErrorMessage;

         $OpenFailCount = $OpenFailCount + 1;

         #
         # Write file name to unable to open file
         #
         print OPEN_FAILED_FILE_NAME $ErrorMessage;
      }
      else
      {
         print "File opened successfully\n";

         #
         # Now loop through the list of files to find any possible matching files
         #
         $SecondaryFileIndex = $PrimaryFileIndex + 1;
       
         while ($SecondaryFileIndex < $NumberOfFiles)    
         {
            if ($FileSize[$PrimaryFileIndex] eq
                $FileSize[$SecondaryFileIndex])
            {
               $SecondaryFile = $DirectoryList[$FileDirectory[$SecondaryFileIndex] - 1].$ActualFiles[$SecondaryFileIndex];
               print "Checking against ".$SecondaryFile."\n";
               #
               # Read the file if we need to
               #
               if ($FileRead == 0)
               {
                  # $_ = join '',(<PRIMARY_FILE>);
                  @PrimaryLines = (<PRIMARY_FILE>);
                  $NumberLines = scalar(@PrimaryLines);   

                  $LineIndex = 0;

                  while ($LineIndex < $NumberLines)
                  {
                     chomp $PrimaryLines[$LineIndex];
                     $LineIndex = $LineIndex + 1;
                  }
                
                  #
                  # Mark the file as read to avoid reading it again 
                  #
                  $FileRead = 1;
               }
              
               #
               # Compare the file
               # 
 
               $OpenStatus = 1;
               open SECONDARY_FILE, $SecondaryFile or $OpenStatus = 0;

               if ($OpenStatus == 0)
               {
                  print "Cannot open secondary file ".$SecondaryFile."\n";
               }
               else
               {
                  $CompareCount = $CompareCount + 1;
                  print "opened ".$SecondaryFile."\n";
 
                  @SecondaryLines = (<SECONDARY_FILE>);

                  $NumberLines = scalar(@SecondaryLines);   
        
                  $LineIndex = 0;

                  while ($LineIndex < $NumberLines)
                  {
                     chomp $SecondaryLines[$LineIndex];
                     $LineIndex = $LineIndex + 1;
                  }
                  #$FileDeleted[$SecondaryFileIndex] = 1;
               }
  
            close SECONDARY_FILE;        
   
         }
         $SecondaryFileIndex = $SecondaryFileIndex + 1;
      }

      close PRIMARY_FILE;
      }

      $PrimaryFileIndex = $PrimaryFileIndex + 1;
   }
}

print "There are ".$DirectoryCount." directories\n";
print "There are ".$FileCount." files to compare\n";
print "Byte count ".$ByteCount."\n";
print "Unable to open ".$OpenFailCount." Files\n";
print "Compare Count ".$CompareCount."\n";

close OPEN_FAILED_FILE_NAME;