;+
;function FILE_CHECKSUM
;Purpose: Returns: SHA1 CHECKSUM string for a file
;Usage:
;    output = file_checksum( filename, [/add_mtime] )
;Typical usage:
;    file_hash( file_search('*') ,/add_mtime )  ;
; Origin:  Mostly copied from file_touch
; Limitations:
;    Currently works only on Linux and MacOs systems by calling the shasum command in a shell.
;    This module is under development.
; Author: Davin Larson (davin@ssl.berkeley.edu)  copyright - March 2014
; Changes:
;    December 2014 - Name changed from file_hash to file_checksum because is better reflects its true purpose
; License:
;   All users are granted permission to use this unaltered code.
;   It may NOT be modified without the consent of the author. However the author welcomes input for bug fixes or upgrades.
;
; $LastChangedBy: ali $
; $LastChangedDate: 2021-05-30 19:47:43 -0700 (Sun, 30 May 2021) $
; $LastChangedRevision: 30011 $
; $URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/spdsoft/trunk/general/misc/file_stuff/file_checksum.pro $
;-

function file_checksum,files,method=method,add_mtime=add_mtime,mtime_format=mtime_format,verbose=verbose,executable=executable,relative_position=relative_position
  common file_checksum_com, hash_init,hash_version,hash_executable,hash_error

  if ~keyword_set(method) then method = 'sha1'

  if ~keyword_set(hash_init)   then begin
    hash_executable = 'shasum'
    if !version.os eq 'linux' then hash_executable = 'sha1sum'
    spawn,hash_executable+' --version',hash_version,hash_error
    hash_init = 4
    if keyword_set(hash_error) then begin
      dprint,dlevel=0,verbose=verbose,'checksum executable: '+hash_executable+' Error:',hash_error
      wait,3
    endif else  dprint,dlevel=1,verbose=verbose,'Using shell executable: '+hash_executable+' Version: ',hash_version[0]
  endif

  if size(/type,files) ne 7 then begin
    dprint,verbose=verbose,'filename required.'
    return,''
  endif

  commands = hash_executable
  ;if keyword_set(cd_to) then spawn,'cd '+cd_to

  n_files = n_elements(files)
  outputs = n_files ne 0 ? strarr(n_files) : ''
  for i=0,n_files-1 do begin
    file = files[i]
    if file_test(/regular,file) eq 0 then begin
      output = 'FileDoesNotExist                          '+file
    endif else if keyword_set(hash_error) then output ='ChecksumExecutableNotAvailable            '+ file else begin
      if !version.os_family eq 'unix' then begin
        dprint,verbose=verbose,dlevel=4,commands
        if keyword_set(relative_position) then begin
          dirname = strmid(file,0,relative_position)
          bname   = strmid(file,relative_position)
          cd,dirname,current=currentdir
          spawn,[commands,bname],/noshell,/stderr,output,exit_status=status
          cd,currentdir
        endif else  spawn,[commands,file],/noshell,/stderr,output,exit_status=status
      endif else if !version.os_family eq 'Windows' then begin
        dprint,verbose=verbose,dlevel=3,'Not tested on Windows OS yet - feel free to fix this!'
        filestring = '"' + file + '"'
        command = strjoin([commands,filestring],' ')
        dprint,verbose=verbose,dlevel=4,command
        spawn,command ,/noshell,/stderr, /hide,output ,exit_status=status
      endif
    endelse
    output =output[0]
    if keyword_set(mtime_format) or keyword_set(add_mtime) then begin
      stat = file_info(file)
      output = time_string(stat.mtime,tformat=mtime_format)+string(stat.size,format='(i12)')+' '+output
    endif
    if keyword_set(output) then dprint,dlevel=3,verbose=verbose,output
    outputs[i] = output
  endfor

  if n_elements(files) eq 1 then outputs=outputs[0]

  return,outputs
end

