#!/bin/bash
# Copyright 2011-2016 Chad Lemmen http://www.lemmen.com
#
# Set the Informix environment
#. /opt/informix/ol_informix.sh
# Set the Aubit environment
#. /etc/profile.d/informix.sh
# Set the Postgres environment
#. /opt/stansoft/etc/postgres.sh

if [ $# = 0 ]; then
    echo "Usage: $0 [sql_where_clause]"
    exit 1
fi

trap 'echo interrupt, now exiting; exit -1' SIGHUP SIGINT SIGTERM

if [ -z "$PGDATA" ] && [ -z "$INFORMIXDIR" ]; then
  echo "Either the Postgres or Informix environment must be set."
  echo ". /opt/stansoft/etc/postgres.sh (make sure to include the dot space)"
  echo "or"
  echo ". \$INFORMIXDIR/ol_informix.sh"
  exit 1
fi

getstate() {
  onstat -  >/dev/null 2>&1
  engine_state=$?
}

if [[ $A4GL_SQLTYPE == pg* ]]; then
  # Postgres
  pg_isready >/dev/null 2>&1
  if [ $? -ne 0 ]; then
    echo "The PostgreSQL database server is not running."
    echo "Start it by running $ssdir/etc/rc.postgresql start"
    exit 1
  fi
  sqlcmd="psql -q -t -A"
else
  # Informix
  getstate
  if [ $engine_state != 5 ]; then
    echo "The database engine is down, or the environment is not set."
    exit 1
  fi
  sqlcmd=dbaccess
  noheading='output to pipe "cat" without headings'
fi


where_clause=$1
ret=0
# Used by Aubit4GL
export DBDATE=y4md-
tmp=/tmp
filelist=$tmp/pjrfilelist-$USER
loadfile=$tmp/parsepos-$USER.unl
bin=`dirname $0`
transdir=/opt/postrans
xslfiles=($bin/pjrfinancial.xsl $bin/pjrsale.xsl $bin/pjrrefund.xsl)
# Set these to the path of your vpnc commands
vpnc=/usr/local/sbin/vpnc
vpncdisconnect=/usr/local/sbin/vpnc-disconnect

# Cannot pipe to eval so instead put command into 
# an array and execute the entire array when called.
sshcmd=(ssh -oStrictHostKeyChecking=no)

# clear screen
clear

# Function to check if a vpn interface is up.
vpn_up() {
  netstat -r | grep -q tun0
  if [ $? -eq 0 ]; then
    # VPN is up
    return 0
  fi

  return 1
}

check_status() {
  status=$@
  if [ "$status" != "0" ]; then
    ret=$status
  fi
}

# Make sure we can find the xsl files before downloading any PJR files
for file in "${xslfiles[@]}"; do
  if [ ! -f "$file" ]; then
    echo "Could not find $file"
    exit
  fi
done

which xsltproc >/dev/null
if [ $? -ne 0 ]; then
  echo "Cannot find xsltproc"
  exit
fi

# Make sure we can run the import program. Not passing a load file will
# cause the program to exit with a 0 status.
"$bin"/rsppositm.4ge >/dev/null
if [ $? -ne 0 ]; then
  echo "Unable to run $bin/rsppositm.4ge"
  exit 1
fi

# Using array instead of piping to while to avoid a subshell otherwise
# the exit status variable can't be passed back to the parent process.
# Simulating a multi-dimensional array by adding a comma delimiter
arr=$($sqlcmd stansoft << END
  $noheading
  select prft_ctr || ',' || prft_ftp_path from sys_prft_ctr where $where_clause
  order by prft_ctr;
END
)

OLDIFS=$IFS
# Set field separator to newline so array elements are split on newline
IFS=$'\n'
for row in ${arr[@]}; do
  # Set positional parameter split by a comma
  IFS=,
  set -- `echo "$row"`
  ctr=$1
  host=$2
  IFS=$OLDIFS

  if [ -z "$host" ]; then # host is null 
    continue
  fi

  # So we can see which store it's processing
  echo $ctr importing transactions...

  cd $transdir
  if [ $? -ne 0 ]; then
    echo "Could not change directory to $transdir"
    exit 1
  fi
  # The xml files are only unique to the system so use different directories
  mkdir -p -m775 $ctr
  cd $ctr
  if [ $? -ne 0 ]; then
    echo "Could not make or change directory to $transdir/$ctr"
    exit 1
  fi


  # Determine if it's a vpn connection or ssh. SSH uses the format user@hostname
  echo "$host" | grep -q '@'
  if [ $? -ne 0 ] && [ "$host" != "localhost" ]; then # It must be a vpn
    # If a vpn connection is already up skip $host
    if vpn_up; then
      echo "VPN already up, skipping $ctr"
      continue
    fi

    # Bring up the vpn connection
    sudo $vpnc "$host" # This will read the /etc/vpnc/$host.conf config file

    # Make sure the vpn connection is up
    if ! vpn_up; then
      echo "VPN is not up, skipping $ctr"
      continue
    fi

    # Now that the vpn connection is up treat it as a local connection
    host="localhost"
    vpn="Y"
  fi

  if [ "$host" = "localhost" ]; then
    # If a vpn connection is already up skip $host
    if vpn_up arg && [ "$vpn" != "Y" ]; then
      echo "VPN already up, skipping $ctr"
      continue
    fi

    # We need to redirect stderr here to get the downloaded file list so that
    # only the most recent download is processed.  Need to use the -DD option
    # to delete remote files after download to prevent duplicates being inserted
    # This could happen if a computer is replaced which doesn't have the 
    # previously downloaded files since `ncftpget' won't download files that
    # already exist locally.
    ncftpget -DD -a -u GilbarcoFTP -p XMLUser4FTP ftp://10.5.60.1/booutbox/PJR* > $filelist 2>&1

    check_status $?

  else # It must be a remote host
    # The -c option of ncftpget writes to stdout, but it doesn't work with 
    # wildcards so we need to get the files first on the remote host then
    # transfer to the office. The -n option of ssh is needed or the while
    # terminates after the first remote host finishes.
    "${sshcmd[@]}" -n $host "mkdir -p postrans; cd postrans; ncftpget -DD -a -u GilbarcoFTP -p XMLUser4FTP ftp://10.5.60.1/booutbox/PJR*" > $filelist 2>&1

    check_status $?

    # Get the files from the remote host... 
    # ncftpget stderr produces multiple lines for each file to show download
    # progress, so we need to use `uniq' here to remove the adjacent duplicates
    # We are transfering the filelist to the remote host and then using it to
    # tar and get the files locally.
    cut -d: -f1 $filelist | uniq | grep "PJR*" | "${sshcmd[@]}" $host "cat - > files; cd postrans; tar czf - -T ../files" | tar xzf -

    check_status $?
  fi

  # Set permissions, needed if run by multiple users since
  # this script deletes old files.
  chmod -f 666 `cut -d: -f1 $filelist`

  # Put the downloaded files into an array. 
  # ncftpget stderr produces multiple lines for each file to show download
  # progress, so we need to use `uniq' here to remove the adjacent duplicates.
  # The PJR files have an invalid format of the first line which xsltproc
  # gives an error for, but still processes the file.  The line should 
  # be <?xml version="1.0" standalone="no"?> notified Gilbarco on 03/04/10
  # and they said it will be fixed in a future upgrade. We could use `sed'
  # here to delete the first line, but it works without doing that.
  files=$(cut -d: -f1 $filelist | uniq | grep "PJR*")

  # Process the PJR files to parse SaleEvent, RefundEvent and FinancialEvent.
  for xsl in "${xslfiles[@]}" 
  do
    # Parse the xml files
    xsltproc $xsl ${files[*]} > "$loadfile"

    # Load file into database tables
    $bin/rsppositm.4ge "$loadfile"
    status=$?
    rm -f "$loadfile"
  done

  # Passport purges files older than 7 days, we'll purge the local directory
  # for anything older than 10 days.  We need to keep at least 7 days so    
  # duplicates don't get downloaded.
  if [ $status == 0 ]; then
    find $transdir/$ctr -mtime +10 -exec rm {} \;
    # Delete old files on remote host
    if [ "$host" != "localhost" ]; then
      "${sshcmd[@]}" -n $host "find postrans -mtime +10 -exec rm {} \;" 
    fi
  else
    ret=$status
    echo "getpos: Get POS files failed!" | mail -s 'getpos failed' $USER
  fi

  if [ "$vpn" = "Y" ]; then
    # Bring down the vpn connection
    sudo $vpncdisconnect
    vpn=""
  fi
done

rm -f $filelist
exit $ret

