#!/bin/sh

# ===========================================================================
#
#                            PUBLIC DOMAIN NOTICE
#            National Center for Biotechnology Information (NCBI)
#
#  This software/database is a "United States Government Work" under the
#  terms of the United States Copyright Act.  It was written as part of
#  the author's official duties as a United States Government employee and
#  thus cannot be copyrighted.  This software/database is freely available
#  to the public for use. The National Library of Medicine and the U.S.
#  Government do not place any restriction on its use or reproduction.
#  We would, however, appreciate having the NCBI and the author cited in
#  any work or product based on this material.
#
#  Although all reasonable efforts have been taken to ensure the accuracy
#  and reliability of the software and data, the NLM and the U.S.
#  Government do not and cannot warrant the performance or results that
#  may be obtained by using this software or data. The NLM and the U.S.
#  Government disclaim all warranties, express or implied, including
#  warranties of performance, merchantability or fitness for any particular
#  purpose.
#
# ===========================================================================
#
# File Name:  test-eutils
#
# Author:  Jonathan Kans
#
# Version Creation Date:   3/12/19
#
# ==========================================================================

# Entrez Direct - EDirect

dir=`dirname "$0"`

cmd="-all"

verby=false
timey=false
failed=false
failures=""
START=0
END=0
DIFF=0

seconds_start=$(date "+%s")

while [ $# -gt 0 ]
do
  case "$1" in
    -all | -alive | -esearch | -elink | -efetch | -esummary )
      cmd=$1
      shift
      ;;
    -verbose )
      verby=true
      shift
      ;;
    -timer | -timed )
      timey=true
      shift
      ;;
    -h | -help | --help )
      cat <<EOF
USAGE: $0
       [ -all | -alive | -esearch | -elink | -efetch | -esummary ]
       [ -verbose ]

EXAMPLE: test-eutils -alive
EOF
      exit 0
      ;;
    -* | * )
      exec >&2
      echo "$0: Unrecognized option $1"
      exit 1
      ;;
  esac
done

MarkFailure() {
  fails="$1"
  res="$2"
  if [ "$failed" != true ]
  then
    if [ "$verby" = true ]
    then
      echo ""
      echo "FAILURE"
      echo ""
    fi
    failed=true
  fi
  if [ "$verby" = true ]
  then
    echo ""
    echo "$fails"
    echo ""
    echo "$res"
    echo ""
  fi
  failures=$(echo "$failures\\n\\n  $fails")
}

DoStart() {
  DIFF=0
  START=$(perl -MTime::HiRes -e 'printf("%.0f\n",Time::HiRes::time()*1000)')
}

DoStop() {
  END=$(perl -MTime::HiRes -e 'printf("%.0f\n",Time::HiRes::time()*1000)')
  DIFF=$(($END - $START))
}

DoTime() {
  if [ "$timey" = true ]
  then
    echo " $DIFF"
  fi
}

DoAlive() {
  DoStart
  res=$(
    nquire -eutils einfo.fcgi -dbs
  )
  DoStop
  tst=$(
    echo "$res" | xtract -pattern DbList -sep "\n" -element DbName |
    sort | uniq | tr '\n' ' '
  )
  case "$tst" in
    *" mesh "* )
      printf "."
      ;;
    * )
      fails="nquire -eutils einfo.fcgi -dbs"
      MarkFailure "$fails" "$res"
      printf "x"
      ;;
  esac
  DoTime

  DoStart
  res=$(
    nquire -eutils elink.fcgi -dbfrom pubmed -db pubmed -id 2539356
  )
  DoStop
  num=$(
    echo "$res" | tr '\n' ' ' | xtract -pattern LinkSet -num "Link/Id"
  )
  if [ $num -lt 100 ]
  then
    fails="nquire -eutils elink.fcgi -dbfrom pubmed -db pubmed -id 2539356"
    MarkFailure "$fails" "$res"
    printf "x"
  else
    printf "."
  fi
  DoTime

  DoStart
  res=$(
    nquire -eutils efetch.fcgi -db pubmed -id 2539356 -rettype native -retmode xml
  )
  DoStop
  tst=$(
    echo "$res" | tr '\n' ' '
  )
  case "$tst" in
    *"Tn3 transposon inserts at a reduced frequency"* )
      printf "."
      ;;
    * )
      fails="nquire -eutils efetch.fcgi -db pubmed -id 2539356 -rettype native -retmode xml"
      MarkFailure "$fails" "$res"
      printf "x"
      ;;
  esac
  DoTime

  DoStart
  res=$(
    nquire -eutils esummary.fcgi -db pubmed -id 2539356 -version 2.0
  )
  DoStop
  tst=$(
    echo "$res" | tr '\n' ' '
  )
  case "$tst" in
    *"Nucleotide sequences required for Tn3 transposition immunity"* )
      printf "."
      ;;
    * )
      fails="nquire -eutils esummary.fcgi -db pubmed -id 2539356 -version 2.0"
      MarkFailure "$fails" "$res"
      printf "x"
      ;;
  esac
  DoTime

  DoStart
  res=$(
    nquire -eutils esearch.fcgi -db pubmed -term "tn3 transposition immunity"
  )
  DoStop
  tst=$(
    echo "$res" | tr '\n' ' '
  )
  case "$tst" in
    *"QueryTranslation>tn3"* )
      printf "."
      ;;
    * )
      fails="nquire -eutils esearch.fcgi -db pubmed -term \"tn3 transposition immunity\""
      MarkFailure "$fails" "$res"
      printf "x"
      ;;
  esac
  DoTime
  printf "\n"
}

DoInfo() {
  DoStart
  res=$(
    einfo -db all
  )
  DoStop
  tst=$(
    echo "$res" | xtract -pattern DbInfo -sep "\n" -element DbName |
    sort | uniq | tr '\n' ' '
  )
  case "$tst" in
    *" mesh "* )
      printf "."
      ;;
    * )
      fails="einfo -db all"
      MarkFailure "$fails" "$res"
      printf "x"
      ;;
  esac
  DoTime
  printf "\n"
}

DoSearch() {
  while read db qy
  do
    DoStart
    res=$(
      esearch -db "$db" -query "$qy" < /dev/null
    )
    DoStop
    num=$(
      echo "$res" | xtract -pattern ENTREZ_DIRECT -element Count
    )
    if [ $num -lt 1 ]
    then
      fails=$(echo "esearch -db \"$db\" -query \"$qy\"")
      MarkFailure "$fails" "$res"
      printf "x"
    else
      printf "."
    fi
    DoTime
  done < "$dir/tst-esearch.txt"
  printf "\n"
}

DoLink() {
  while read db tg id
  do
    DoStart
    res=$(
      elink -db "$db" -target "$tg" -id "$id"
    )
    DoStop
    num=$(
      echo "$res" | xtract -pattern ENTREZ_DIRECT -element Count
    )
    if [ $num -lt 1 ]
    then
      fails=$(echo "elink -db \"$db\" -target \"$tg\" -id \"$id\"")
      MarkFailure "$fails" "$res"
      printf "x"
    else
      printf "."
    fi
    DoTime
  done < "$dir/tst-elink.txt"
  printf "\n"
}

DoFetch() {
  while read db ft id mt
  do
    DoStart
    res=$(
      efetch -db "$db" -id "$id" -format "$ft"
    )
    DoStop
    tst=$(
      echo "$res" | tr '\n' ' '
    )
    case "$tst" in
      *"$mt"* )
        printf "."
        ;;
      * )
        fails=$(echo "efetch -db \"$db\" -id \"$id\" -format \"$ft\"")
        MarkFailure "$fails" "$res"
        printf "x"
        ;;
    esac
    DoTime
  done < "$dir/tst-efetch.txt"
  printf "\n"
}

DoSummary() {
  while read db id
  do
    DoStart
    res=$(
      esummary -db "$db" -id "$id"
    )
    DoStop
    tst=$(
      echo "$res" | xtract -pattern DocumentSummary -element DocumentSummary/Id
    )
    if [ "$tst" != "$id" ]
    then
      fails=$(echo "esummary -db \"$db\" -id \"$id\"")
      MarkFailure "$fails" "$res"
      printf "x"
    else
      printf "."
    fi
    DoTime
  done < "$dir/tst-esummary.txt"
  printf "\n"
}

case "$cmd" in
  -all )
    echo "alive"
    DoAlive
    echo "einfo"
    DoInfo
    echo "esearch"
    DoSearch
    echo "elink"
    DoLink
    echo "efetch"
    DoFetch
    echo "esummary"
    DoSummary
    ;;
  -alive )
    DoAlive
    ;;
  -einfo )
    DoInfo
    ;;
  -esearch )
    DoSearch
    ;;
  -elink )
    DoLink
    ;;
  -efetch )
    DoFetch
    ;;
  -esummary )
    DoSummary
    ;;
  * )
    break
    ;;
esac

seconds_end=$(date "+%s")
seconds=$((seconds_end - seconds_start))

if [ "$failed" = true ]
then
  echo ""
  echo "Failure in test-eutils commands:"
  echo "$failures"
  echo ""
  echo ""
  echo "Elapsed time $seconds seconds"
  echo ""
  exit 1
fi

echo "Successful completion in $seconds seconds"
