#!/bin/sh

# Public domain notice for all NCBI EDirect scripts is located at:
# https://www.ncbi.nlm.nih.gov/books/NBK179288/#chapter6.Public_Domain_Notice

# pm-prepare

pth=$( dirname "$0" )

case "$pth" in
  /* )
    ;; # already absolute
  *  )
    pth=$(cd "$pth" && pwd)
    ;;
esac

case ":$PATH:" in
  *:"$pth":* )
    ;;
  * )
    PATH="$PATH:$pth"
    export PATH
    ;;
esac

# handle common flags - dot command is equivalent of "source"

if [ ! -f "$pth"/xcommon.sh ]
then
  echo "ERROR: Unable to find '$pth/xcommon.sh' file" >&2
  exit 1
fi

. "$pth"/xcommon.sh

# initialize specific flags

dbase=""
verbose=false

while [ $# -gt 0 ]
do
  case "$1" in
    -db )
      dbase=$2
      shift
      shift
      ;;
    -* )
      exec >&2
      echo "$0: Unrecognized option $1" >&2
      exit 1
      ;;
    * )
      break
      ;;
  esac
done

if [ -z "$dbase" ]
then
  echo "Must supply database in -db argument" >&2
  exit 1
fi

WriteCacheDirTag() {

  path="$1"

  if [ ! -f "$path/CACHEDIR.TAG" ]
  then
  cat >$path/CACHEDIR.TAG <<EOF
Signature: 8a477f597d28d172789f06886806bc55
# This file is a cache directory tag created by edirect.
# For information about cache directory tags, see:
#   http://www.brynosaurus.com/cachedir/
EOF
  fi
}

for dir in Archive Postings Source Index Invert Merged
do
  target=$( FindLocalArchiveFolder "$dbase" "$dir" "false" )
  # remove trailing slash
  target=${target%/}
  if [ -n "$target" ] && [ -d "$target" ] && [ ! -f "${target}/CACHEDIR.TAG" ]
  then
    WriteCacheDirTag "$target"
    verbose=true
  fi
done

if [ "$verbose" = false ]
then
  exit 0
fi

HardDriveWarning() {

  path="$1"

  echo "" >&2
  echo "$path IS ON A HARD DISK DRIVE, NOT THE EXPECTED SOLID-STATE DRIVE." >&2
  echo "" >&2
  echo "WOULD YOU LIKE TO PROCEED WITH ARCHIVING EVEN THOUGH IT IS NOT RECOMMENDED? [y/N]" >&2
  read response
  case "$response" in
    [Yy]*      ) echo "OK, PROCEEDING." >&2 ;;
    [Nn]* | '' ) echo "Holding off, then." >&2; exit 1 ;;
    *          ) echo "Conservatively taking that as a no." >&2; exit 1 ;;
  esac
}

NonAPFSWarning() {

  path="$1"
  ftyp="$2"

  echo "" >&2
  echo "$path IS OF TYPE '$ftyp'" >&2
  echo "" >&2
  echo "IT NEEDS TO BE REFORMATTED AS APFS BEFORE YOU CAN PROCEED:" >&2
  echo "" >&2
  echo "  Run Utilities -> Disk Utility" >&2
  echo "" >&2
  echo "  Switch the View option to 'Show All Devices'." >&2
  echo "" >&2
  echo "  Select the entry named 'PCIe SSD Media' (not the two entries indented below it)." >&2
  echo "" >&2
  echo "  Click on 'Erase'." >&2
  echo "" >&2
  echo "  Change the Scheme to 'GUID Partition Map' (which will expand the Format choices)." >&2
  echo "" >&2
  echo "  Set the Format to 'APFS'." >&2
  echo "" >&2
  echo "  Press Erase." >&2
  echo "" >&2
  echo "ALSO RUN:" >&2
  echo "" >&2
  echo "  sudo trimforce enable" >&2
  echo "" >&2
  echo "IF NECESSARY TO ENABLE TRIM SUPPORT ON THE SOLID STATE DRIVE." >&2
  echo "" >&2
  echo "WOULD YOU LIKE TO PROCEED WITH ARCHIVING ON THE NON-APFS VOLUME ANYWAY? [y/N]" >&2
  read response
  case "$response" in
    [Yy]*      ) echo "OK, PROCEEDING." >&2 ;;
    [Nn]* | '' ) echo "Holding off, then." >&2; exit 1 ;;
    *          ) echo "Conservatively taking that as a no." >&2; exit 1 ;;
  esac
  echo "" >&2
}

MacInstructions() {

  path="$1"

  echo "" >&2
  echo "  To prepare the $path disk for an EDirect archive, please disable:" >&2
  echo "" >&2
  echo "    Antivirus scanning" >&2
  echo "    Spotlight indexing" >&2
  echo "    Time Machine backups" >&2
  echo "" >&2
  echo "  for the '$path' directory:" >&2
  echo "" >&2
  echo "    sudo mdutil -i off ${path}" >&2
  echo "    sudo mdutil -E ${path}" >&2
  echo "    sudo touch ${path}/.fseventsd/no_log" >&2
}

LinuxInstructions() {

  path="$1"

  echo "" >&2
  echo "  To prepare the $path disk for an EDirect archive, please disable:" >&2
  echo "" >&2
  echo "    Antivirus scanning" >&2
  echo "" >&2
  echo "  for the '$path' directory." >&2
  echo "" >&2
  echo "  You may also need to run a command like:" >&2
  echo "" >&2
  echo "    sudo mkfs -t ext4 -b 1024 -I 128 -i 4096 /dev/<device-name>" >&2
  echo "" >&2
  echo "  to configure the file system for a large number of inodes." >&2
}

PrepareDrive() {

  volume="$1"

  if [ "$osname" = "Darwin" ]
  then
    root=$(df $volume | awk 'END { print $NF }')
    sdst=$(diskutil info -plist $root | plutil -extract SolidState xml1 - -o - |  sed -ne 's,<,,pg' | sed -ne 's,/>,,pg')
    if [ "$sdst" != "true" ]
    then
      HardDriveWarning "$volume"
    fi
    ftyp=$(diskutil info -plist $root | plutil -extract FilesystemType xml1 - -o - | sed -ne 's,</*string>,,pg')
    if [ "$ftyp" != "apfs" ]
    then
      NonAPFSWarning "$volume" "$ftyp"
    fi
    MacInstructions "$volume"

    echo "" >&2
  fi

  if [ "$osname" = "Linux" ]
  then
    dev=$( df $volume | awk '/^\/dev\// { print $1 }' )
    if [ -z "$dev" ]
    then
      echo "Unable to confirm remote file system's underlying storage type" >&2
      echo "" >&2
      echo "WOULD YOU LIKE TO PROCEED WITH ARCHIVING ON THIS UNKNOWN STORAGE TYPE? [y/N]" >&2
      read response
      case "$response" in
        [Yy]*      ) echo "OK, PROCEEDING." >&2 ;;
        [Nn]* | '' ) echo "Holding off, then." >&2; exit 1 ;;
        *          ) echo "Conservatively taking that as a no." >&2; exit 1 ;;
      esac
      echo "" >&2
    else
      basedev=$( realpath "$dev" | sed -e 's,/dev/,,; s/\([a-z]\)[0-9]*$/\1/' )
      isHDD=$( grep 1 /sys/block/$basedev/queue/rotational )
      if [ -n "$isHDD" ]
      then
        HardDriveWarning "$volume"
      fi
    fi
    LinuxInstructions "$volume"

    echo "" >&2
  fi

  if [ "$osname" = "CYGWIN_NT" ]
  then
    echo "" >&2
    echo "  To prepare the disk for an EDirect archive, please disable:" >&2
    echo "" >&2
    echo "    Antivirus scanning" >&2
    echo "" >&2
    echo "  for the '$volume' directory." >&2
    echo "" >&2

    if reg query 'HKLM\System\CurrentControlSet\Control\FileSystem' \
      /v NtfsDisable8dot3NameCreation | fgrep -q 0x0
    then
      echo "  Also ask your administrator to set:" >&2
      echo "" >&2
      echo "    NtfsDisable8dot3NameCreation" >&2
      echo "" >&2
      echo "  in the Windows Registry." >&2
      echo "" >&2
    fi
  fi
}

# note that Source is NOT included because it can reside on a rotating hard disk

for dir in Archive Data Postings Extras Index Invert Merged Scratch
do
  target=$( FindLocalArchiveFolder "$dbase" "$dir" "false" )
  # remove trailing slash
  target=${target%/}
  # remove trailing folder name
  target=${target%/*}
  # remove trailing database name
  volume=${target%/*}
  echo "$volume"
done |
sort -f | uniq -i |
while read vol
do
  if [ -n "$vol" ] && [ -d "$vol" ]
  then
    echo "Preparing $vol" >&2
    PrepareDrive "$vol"
  fi
done

exit 0
