#!/bin/bash

vers=2022.09.22.A
# rename files in cwd using creation date in file'x EXIF data
# try to maintain filename if renamed


switch_debugging=$1
swith_confirm=
switch_posthide=1
switch_dryrun=


cd "${0%/*}"

tempfile="temp"



registers=0
register () {
local i key
key=$1
for ((i=0;i<registers;i++)) ; do
  if [ "$key" == "${registered[i]}" ] ; then
    duplicate=1
    unique=
    return
  fi
done
registered[registers++]="$key"
duplicate=
unique=1
}

# use:
#   register "mykey"   or   for n in * ; do register "$n" ; done
#   if [ $duplicate ] ; then echo "duplicate" ; fi
#   if [ $unique ] ; then echo "unique, registgered" ; fi










debug () {
if [ $switch_debugging ] ; then
  echo "DEBUG: $1" 1>&2
fi
}


ls | grep "\..\{3,3\}$" > "$tempfile"

files=0
while read file[files] ; do
  ((files++))
done < "$tempfile"
rm "$tempfile"
debug "found $files files"


# register current filenames
for n in * ; do register "$n" ; done



echo "scanning..."
hits=0
for ((i=0;i<files;i++)) ; do
  f=${file[i]}
  fn=${f%.*}
  e=${f##*.}

  if ! [ -f "$f" ] ; then
    debug "object \"$f\" is not a file, skipping"
    continue
  fi

  if [ "$e" == "$f" ] ; then
    debug "filename \"$f\" doesn't contain a period, skipping"
    continue
  fi

  stamp=
  replace_name=

  if [ -z "$stamp" ] ; then
    # get content creation date
    stamp=$(mdls "$f" | grep "kMDItemContentCreationDate ")  # "kMDItemContentCreationDate             = 2011-05-01 22:16:40 +0000"    (trailing space in grep is necessary)
    debug "stamp=\"$stamp\""
    stamp=${stamp#* = }  # "2011-05-01 22:16:40 +0000"  # keep timezone offset
    debug "stamp=\"$stamp\""
    if [ -n "$stamp" ] ; then
      stamp=$(date -j -f "%Y-%m-%d %H:%M:%S %z" "$stamp" "+%Y.%m.%d %H.%M.%S")  # "2011.05.01 17.16.40"
      debug "stamp=\"$stamp\""
    fi
  fi

  #if [ -z "$stamp" ] ; then
  #  # get file system creation date   THIS IS VERY UNRELIABLE
  #  stamp=$(mdls "$f" | grep "kMDItemFSCreationDate ")  # "kMDItemFSCreationDate             = 2011-05-01 22:16:40 +0000"    (trailing space in grep is necessary)
  #  debug "stamp=\"$stamp\""
  #  stamp=${stamp#* = }  # "2011-05-01 22:16:40 +0000"  # keep timezone offset
  #  debug "stamp=\"$stamp\""
  #  if [ -n "$stamp" ] ; then
  #    stamp=$(date -j -f "%Y-%m-%d %H:%M:%S %z" "$stamp" "+%Y.%m.%d %H.%M.%S")  # "2011.05.01 17.16.40"
  #    debug "stamp=\"$stamp\""
  #  fi
  #fi

  if [ -z "$stamp" ] ; then
    # get Aperture filename date
    stamp=${f:0:23}  # "2001-05-17 at 07-36-52."
    debug "stamp=\"$stamp\""
    stamp=$(date -j -f "%Y-%m-%d at %H-%M-%S." "$stamp" "+%Y.%m.%d %H.%M.%S" 2> /dev/null)  # "2001.05.17 07.36.52"
    debug "stamp=\"$stamp\""
    if [ -n "$stamp" ] ; then
      replace_name=1
    fi
  fi

  if [ -z "$stamp" ] ; then
    # get file's creation date (we do not like using this but sometimes we have to)
    stamp=$(stat -f "%B" "$f")
    debug "stamp=\"$stamp\""
    if [ -n "$stamp" ] ; then
      stamp=$(date -j -f "%s" "$stamp" "+%Y.%m.%d %H.%M.%S" 2> /dev/null)  # "2001.05.17 07.36.52"
      debug "stamp=\"$stamp\""
    fi
  fi

  if [ -z "$stamp" ] ; then
    echo "failed to determine creation date of file \"$f\", skipping"
    continue
  fi
  n="$stamp"

  ft=${f:0:10}
  ts=${n:0:10} 
  if [ "${ft}" == "${ts}" ] ; then
    debug "file \"$f\" already has the correct date prefix, skipping"
    continue
  fi

  if [ $replace_name ] ; then
    debug "will replace name on file \"$f\" with timestamp"
    name[hits]="$stamp"
  #elif (echo "$fn" | grep -q "^[A-Z]\{3,4\}_\?[0-9]\{2,4\}$") ; then
  elif (echo "$fn" | grep -q "^[A-Z]\{3,4\}_\?[0-9]\{2,4\}\( ([1-9])\)\?$") ; then
    debug "file \"$f\" looks like a DCIM name, will replace name with timestamp"
    name[hits]="$stamp"
  elif (echo "$fn" | grep -q "^img\?[0-9]\{3,3\}\( ([1-9])\)\?$") ; then
    debug "file \"$f\" looks like a DCIM name, will replace name with timestamp"
    name[hits]="$stamp"
  elif (echo "$fn" | grep -q "^P[0-9]\{7,7\}\( ([1-9])\)\?$") ; then
    debug "file \"$f\" looks like a Panasinic DCIM name, will replace name with timestamp"
    name[hits]="$stamp"
  else
    debug "file \"$f\" looks like it was renamed, will prepend timestamp to current name"
    name[hits]="$stamp ${fn}"
  fi

  ext[hits]="$e"
  ((hits++))
done

if [ $hits == 0 ] ; then
  echo "nothing to change"
  exit 0
fi

if [ $swith_confirm ] ; then
  echo
  for ((i=0;i<hits;i++)) ; do
    source=${file[i]}
    target="${name[i]}.${ext[i]}"
    echo "mv \"$source\" \"$target\""
  done
  echo
  read -p "press RETURN to rename files : " -n1 x
fi

for ((i=0;i<hits;i++)) ; do
  source=${file[i]}
  target="${name[i]}.${ext[i]}"
  if [ -e "$target" ] ; then
    echo "skipping dup target name \"$target\"" 1>&2
  fi
  echo "mv \"$source\" \"$target\""
  if ! [ $switch_dryrun ] ; then
    register "$target"
    if [ $unique ] ; then
      mv "$source" "$target"
    else
      echo "skipping duplicate registeration \"$source\" to \"$target\""
    fi
  fi
done
echo
echo "done"
echo

# hide us if switched
if [ $switch_posthide ] ; then
  if ! [ $switch_dryrun ] ; then
    osascript -e 'tell application "System Events" to set visible of application process "Terminal" to false'
  fi
fi














