#!/bin/bash

# ===========================================================================
#
#                            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:  xfetch
#
# Author:  Jonathan Kans, Aaron Ucko
#
# Version Creation Date:   01/11/2025
#
# ==========================================================================

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=""
flag="none"
turbo=false
stream=false

recname=""
settag=""
xmltag=""
doctype=""
recskip=0

while [ $# -gt 0 ]
do
  case "$1" in
    -version )
      version=$( einfo -version )
      echo "$version"
      exit 0
      ;;
    -h | -help | --help | help )
      version=$( einfo -version )
      echo "xfetch $version"
      echo ""
      echo "USAGE: xfetch"
      echo "       -db"
      echo "       -id"
      echo "       -input"
      echo "       -stream"
      echo ""
      exit 0
      ;;
    * )
      break
      ;;
  esac
done

while [ $# -gt 0 ]
do
  tag="$1"
  rem="$#"
  case "$tag" in
    -strict )
      flag="strict"
      shift
      ;;
    -mixed )
      flag="mixed"
      shift
      ;;
    -flag )
      flag=$2
      shift
      shift
      ;;
    -db )
      CheckForArgumentValue "$tag" "$rem"
      shift
      dbase="$1"
      shift
      ;;
    -id )
      CheckForArgumentValue "$tag" "$rem"
      shift
      ids="$1"
      shift
      while [ $# -gt 0 ]
      do
        case "$1" in
          -* )
            break
            ;;
          * )
            # concatenate run of UIDs with commas
            ids="$ids,$1"
            shift
            ;;
        esac
      done
      ;;
    -input )
      CheckForArgumentValue "$tag" "$rem"
      shift
      input="$1"
      shift
      ;;
    -tag )
      recname=$2
      shift
      shift
      ;;
    -skip )
      recskip=$2
      shift
      shift
      ;;
    -xml )
      xmltag=$2
      shift
      shift
      ;;
    -doctype )
      doctype=$2
      shift
      shift
      ;;
    -set )
      settag=$2
      shift
      shift
      ;;
    -turbo )
      turbo=true
      shift
      ;;
    -stream )
      stream=true
      shift
      ;;
    -* )
      exec >&2
      echo "$0: Unrecognized option $1"
      exit 1
      ;;
    * )
      break
      ;;
  esac
done

# check for ENTREZ_DIRECT message or piped UIDs unless database and UIDs provided in command line

if [ -z "$dbase" ]
then
  ParseStdin
elif [ -z "$ids" ] && [ -z "$input" ]
then
  ParseStdin
fi

# set pubmed as default database for the time being
if [ -z "$dbase" ]
then
  dbase="pubmed"
fi

# eventually will require explicit database in argument or piped message
if [ -z "$dbase" ]
then
  echo "Must supply database in -db argument"
  exit 1
fi

# normalize date arguments

FixDateConstraints

# get path to local archive folder

FindArchiveFolder

# get database-specific parameters from xfetch.ini configuration file

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

mssg=$(
  cat "${pth}/xfetch.ini" |
  ini2xml |
  xtract -rec Rec -pattern "ConfigFile/*" -select "$dbase" |
  tr '\n' ' '
)
if [ -n "$mssg" ]
then
  ParseConfig "$mssg" Rec recname name settag set xmltag xml doctype doctype recskip skip
fi

if [ -z "$recname" ] || [ -z "$settag" ]
then
  echo "ERROR: Missing -tag or -set from database-specific wrapper in xfetch.ini file" >&2
  exit 1
fi

# call rchive -stream


if [ "$stream" = true ]
then
  GetUIDs |
  rchive -db "$dbase" -tag "$recname" -skip "$recskip" -flag "$flag" -stream "$archiveBase"

  exit 0
fi

# call rchive -fetch

if [ -n "$xmltag" ]
then
  echo "$xmltag"
fi
if [ -n "$doctype" ]
then
  echo "$doctype"
fi
if [ -n "$settag" ]
then
  echo "<${settag}>"
fi
if [ "$turbo" = true ]
then
  GetUIDs |
  rchive -gzip -db "$dbase" -tag "$recname" -flag "$flag" -turbo -fetch "$archiveBase"
else
  GetUIDs |
  rchive -gzip -db "$dbase" -tag "$recname" -flag "$flag" -fetch "$archiveBase"
fi
if [ -n "$settag" ]
then
  echo "</${settag}>"
fi

exit 0
