#!/bin/sh

# History:
# 2021-07-01: Made -t use PATTERN instead of FILE for .ppf files.
# 2020-09-24: Fixed a bug with imucal files not being included
# 2020-05-06: Fixed a bug with -t when there was a disabled IMU
# 2019-09-09: Changed -t to use FILE instead of IMUCAL for .imucal files.
# 2019-08-19: Added -t option.
# 2019-02-14: Now handles IMU sections.
# 2017-04-25: Fixed a bug where it would list non-existing .anm files
# 2017-01-25: Now handles .imucal files
# 2014-12-17: Now handles GIANT_DATA_DIR as well as BIO_DATA_DIR
# 2008-10-22: Added ability to take multiple files

data_dir=${GIANT_DATA_DIR%/}

if [ "$data_dir" = "" ]; then
  data_dir=${BIO_DATA_DIR%/}
fi

full_path_name() {
  if [ ${1#/} = $1 ]; then
    # No leading /
    # must be an easier way to do this
    cwd=`pwd`
    dn=`dirname $1`
    cd $dn || exit 1
    dir=`/bin/pwd`
    cd $cwd || exit 1
    echo $dir/`basename $1`
  else
    # Has a leading /
    echo $1
  fi
}


toppsffiles () {
  psf="$1"
  awk '
    function expand(x)
    {
      gsub("\\$BIO_DATA_DIR/","",x);
      gsub("\\$GIANT_DATA_DIR/","",x);
      gsub("\\$NU_DATA_DIR/","",x);
      return x;
    }

    function extract_imucal(x)
    {
      n = length(x)
      fieldnum = 0
      desired_field = 5
      for (i=1; i<=n;) {
        c = substr(x,i,1)
        while (c==" ") {
          ++i
          c = substr(x,i,1)
        }
        ++fieldnum
        if (c=="{") {
          ++i
          field = ""
          for (;;) {
            c = substr(x,i,1)
            ++i
            if (c=="}" || c=="") break
            field = field c
          }
        }
        else {
          field = c
          ++i
          for (;;) {
            c = substr(x,i,1)
            if (c==" " || c=="") break
            field = field c
            ++i
          }
        }
        if (fieldnum==desired_field) {
          return field
        }
      }
    }

    $1=="SUBJECT" && $2=="{" {
      pattern=""
      charmap=""
      target_anim=""
      enabled=0
      project=""
      imucal=""
    }

    $1=="ENABLED:" && !in_imu_section { enabled=$2+0 }
    $1=="PROJECT:" { project=$2; }
    $1=="PATTERN:" { pattern=$2 }
    $1=="CHARMAP:" { charmap=$2 }
    $1=="TARGET_ANIM:" { target_anim=$2; }
    $1=="IMU:" {
      imucal=extract_imucal($0)
      if (imucal!="") {
        print "FILE: "expand(imucal)
        imucal=""
      }
    }
    $1=="IMU" && $2=="{" { in_imu_section = 1; next; }
    $1=="}" && in_imu_section {
      in_imu_section = 0;
      if (imucal!="") {
        print "FILE: "expand(imucal);
        imucal=""
      }
      next;
    }
    $1=="CALIBRATION:" && in_imu_section { imucal=$2; }
    $1=="}" {
      if (enabled) {
        print "PROJECT: "expand(project);
        if (pattern!="") {
          print "PATTERN: "expand(pattern);
        }
        if (charmap!="") {
          print "FILE: "expand(charmap);
        }
        if (target_anim!="") {
          print "ANIMATION: "expand(target_anim);
        }
      }
    }
  ' <"$psf"
}


listpsffiles() {
  for psf in "$@"; do
    psf=`full_path_name "$psf"`
    if [ $? != 0 ]; then
      exit 1
    fi
    # remove the substring equal to the value of
    # $BIO_DATA_DIR and a "/"
    local_psf=${psf#$data_dir/}
    echo "PSF: $local_psf"
    toppsffiles "$psf"
  done | sort | uniq | awk -v data_dir=$data_dir '
    function fullpath(x)
    {
      if (match(x,"^/.*")) {
        return x
      } else {
        return data_dir"/"x
      }
    }
    $1=="PROJECT:" {
      file=fullpath($2)
      print "Getting files from "file >"/dev/stderr"
      system("tarprj -l "file)
      next
    }
    $1=="ANIMATION:" {
      file=fullpath($2)
      print "Getting files from "file >"/dev/stderr"
      system("taranim -l "file)
      next
    }
    { print $2 }
  ' | sort | uniq
  if [ $? != 0 ]; then
    exit 1
  fi
}

listonly=0
toponly=0
tar_file=""

while :;do
  if [ x"$1" = x"-l" ]; then
    listonly=1
    shift
  elif [ x"$1" = x"-t" ]; then
    toponly=1
    shift
  elif [ x"$1" = x"-c" ]; then
    tar_path=`full_path_name "$2"`
    # strip off .tar.gz since this will be added back later
    tar_file=`basename "$tar_path" .gz`
    tar_file=`basename "$tar_file" .tar`
    tar_file=`dirname "$tar_path"`/$tar_file
    shift 2
  else
    break
  fi
done

if [ $# = 0 ]; then
  (
    echo
    echo "Usage: tarpsf <psf file>"
    echo "  Create a .tar.gz file for the given problem setup file."
    echo
    echo "Usage: tarpsf -l <psf file> [<psf file> ...]"
    echo "  List the files related to the given problem setup files."
    echo
    echo "Usage: tarpsf -t <psf file> [<psf file> ...]"
    echo "  List files directly referenced by the given problem setup files."
    echo
    echo "Usage: tarpsf -c <tar file> <psf file> [<psf file> ...]"
    echo "  Create a .tar.gz file for the given problem setup files."
    echo
  ) >&2
  exit 1
fi

if [ $toponly = 1 ]; then
  for psf in "$@"; do
    toppsffiles "$psf" || exit 1
  done
  exit 0
fi

if [ $listonly = 0 ]; then
  if [ x"$tar_file" = x ]; then
    if [ $# -gt 1 ]; then
      echo >&2
      echo "-c must be specified if multiple files are given." >&2
      echo >&2
      exit 1
    else
      psf=`full_path_name "$1"`
      if [ $? != 0 ]; then
        exit 1
      fi
      tar_file=`pwd`/`basename "$psf"`
    fi
  fi
fi

files=`listpsffiles "$@"`

if [ $? != 0 ]; then
  exit 1
fi

if [ $listonly = 1 ]; then
  echo "$files"
else
  cd $data_dir
  echo
  echo "$files" | xargs tar zcvf "$tar_file".tar.gz
  echo
  echo "Created $tar_file.tar.gz"
  echo
fi
