package require md5

#
# The state for this application is held in a keyed list
#  The key is an md5 hash
#  The value is list of files with that hash
#
source keyedListLibByReference.tcl

# Add a new procedure to append a new element onto the value
# associated with a key
################################################################
# proc addToKey {listName key newvalue}--
#    Add two new elements to the value in a keyed list
# Arguments
#   listName	The name of the keyed list
#   key		The key to find in the list
#   value1	The first element to add (full path)
#   value2 	The second element to add (md5 hash)
# 
# Results
#   The list will be modified in place.
# 
proc addToKey {listName key newvalue } {
  upvar $listName list
  
  set value [getValue list $key]
  lappend value $newvalue
  appendKeyedPair list $key $value
}

################################################################
# proc processFolder {folderName}--
#    examine contents of a folder and add the file paths and md5 
#    values to the list.
#    Recursively descend into subfolders.
# Arguments
#   folderName	Name of a folder to process
# 
# Results
#   global list Md5Paths is modified
# 
proc processFolder {folderName} {
  global Md5Paths

  foreach item [glob -nocomplain $folderName/*] {
    set type [file type $item]
    if {$type eq "directory"} {
      processFolder $item
    } elseif {$type eq "file"} {
      set md5 [md5::md5 -hex -filename $item]
      addToKey Md5Paths $md5 $item 
    }
  }
}

# Initialize the keyed list to empty
set Md5Paths {}

# Start the recursive processing
processFolder [pwd]/[lindex $argv end]

# Report the results
foreach {key matches} $Md5Paths {
  if {([llength $matches] > 1)} {
    puts "These files are identical: "
    foreach path $matches {
      puts "  $path"
    }
  }
}
