#!/bin/ksh

while getopts ":c:t:flradgh" opt
do
  case $opt in
    c ) CONTROL_URL=$OPTARG ;;
    t ) TEST_URL=$OPTARG ;;
    f ) FUNC_TESTS=true ;;
    l ) LOCAL_TESTS=true ;;
    r ) REMOTE_TESTS=true ;;
    a ) FUNC_TESTS=true
        LOCAL_TESTS=true
        REMOTE_TESTS=true ;;
    d ) DELETE=true ;;
    g ) DEBUG=true ;;
    h ) HELP=true ;;
    \? ) echo "Invalid option"
        HELP=true
        break ;;
  esac
done
if [[ $# != $(($OPTIND - 1)) ]]; then
  echo "Invalid argument"
  HELP=true
fi

if [[ $HELP == true ]]; then
 echo 'Usage: run_tests [options]'
 echo 'Valid options:'
 echo '-c URL'
 echo '   Generate the control results using the version of FCM at "URL"'
 echo '-t URL'
 echo '   Generate the test results using the version of FCM at "URL"'
 echo '-f'
 echo '   Perform the functional tests'
 echo '-l'
 echo '   Perform the local performance tests'
 echo '-r'
 echo '   Perform the remote performance tests'
 echo '-a'
 echo '   Perform all the tests (equivalent to -flr)'
 echo '-d'
 echo '   Remove any previous test results before starting'
 echo '-g'
 echo '   Output additional diagnostics'
 echo '-h'
 echo '   Print this help message'
 exit 1
fi

if [[ -n "$CONTROL_URL" ]]; then
  TYPES="control"
fi
if [[ -n "$TEST_URL" ]]; then
  TYPES="$TYPES test"
fi
if [[ -z "$TYPES" ]]; then
  echo "Either a control or a test URL must be specified"
  exit 1
fi

export HPC=hpc1e
export BASE_DIR_HPC=$(ssh $HPC 'echo $PWD')/fcm_test_suite

export BASE_DIR=$LOCALTEMP/fcm_test_suite
if [[ $DELETE == true ]]; then
  if [[ $DEBUG == true ]]; then
    echo "Removing any previous test directory ..."
  fi
  rm -rf $BASE_DIR
  ssh $HPC "rm -rf $BASE_DIR_HPC"
fi
mkdir -p $BASE_DIR

export REPOS_DIR=$BASE_DIR/test_svn
export REPOS_URL="file://$REPOS_DIR"
if [[ ! -d $REPOS_DIR ]]; then
  echo "$(date): Creating test repository ..."
  ./create_repos > $BASE_DIR/repos.stdout 2> $BASE_DIR/repos.stderr
fi

cp compare_results $BASE_DIR
PATH_BASE=$PWD/wrapper_scripts:$PATH:~opsrc/ops0/mpi/mpich2-1.0.8p1-ukmo-v2/ifort-10/bin

export DEBUG
export TYPE
for TYPE in $TYPES
do
  if [[ $TYPE == test ]]; then
    URL=$TEST_URL
  else
    URL=$CONTROL_URL
  fi
  URL_BASE=${URL%@*}
  REV=${URL#$URL_BASE}
  URL=$URL_BASE$REV
  fcm ls $URL/bin/fcm >/dev/null 2>&1
  if [[ $? != 0 ]]; then
    echo 'URL must be a URL or the path to a working copy of the FCM project tree'
    exit 1
  fi
  echo FCM version to be used:
  fcm info $URL | grep URL
  fcm info $URL | grep Revision

  export RUN_DIR=$BASE_DIR/$TYPE
  rm -rf $RUN_DIR
  mkdir $RUN_DIR

  if [[ $DEBUG == true ]]; then
    echo "Creating local copy of FCM ..."
  fi
  fcm export -q $URL $RUN_DIR/fcm
  echo "set::url::test_suite $REPOS_URL" >>$RUN_DIR/fcm/etc/fcm.cfg
  export PATH=$RUN_DIR/fcm/bin:$PATH_BASE

  if [[ $FUNC_TESTS == true ]]; then
    . ./tests_functional.list
    export COMPARE_TIMES=false
    let failed=0
    for TEST in $TESTS
    do
      ./test_scripts/$TEST
      if [[ $? != 0 ]]; then
        let failed=failed+1
      fi
    done

    echo "$(date): Functional tests finished"
    if [[ $failed == 0 ]]; then
      echo "SUMMARY: All functional tests succeeded"
    else
      echo "SUMMARY: $failed functional tests failed"
    fi
  fi

  if [[ $LOCAL_TESTS == true ]]; then
    . ./tests_perf_local.list
    export COMPARE_TIMES=true
    let failed=0
    for TEST in $TESTS
    do
      ./test_scripts/$TEST
      if [[ $? != 0 ]]; then
        let failed=failed+1
      fi
    done

    echo "$(date): Local performance tests finished"
    if [[ $failed == 0 ]]; then
      echo "SUMMARY: All local performance tests succeeded"
    else
      echo "SUMMARY: $failed local performance tests failed"
    fi
  fi

  if [[ $REMOTE_TESTS == true ]]; then
    if [[ $DEBUG == true ]]; then
      echo "Copying files to HPC platform ..."
    fi
    export RUN_DIR_HPC=$BASE_DIR_HPC/$TYPE
    ssh $HPC "rm -rf $RUN_DIR_HPC"
    ssh $HPC "mkdir -p $RUN_DIR_HPC"
    rsync -a --rsh="ssh" $RUN_DIR/fcm $HPC:$RUN_DIR_HPC
    rsync -a --rsh="ssh" compare_results report_hpc_results $HPC:$BASE_DIR_HPC

    BATCH_SCRIPT_NAME=hpc_batch.sh
    export BATCH_DIRS_NAME=hpc_dirs.sh
    export BATCH_SCRIPT=$RUN_DIR/$BATCH_SCRIPT_NAME
    ./create_hpc_batch_script
    export BATCH_DIRS=$RUN_DIR/$BATCH_DIRS_NAME

    echo 'TESTS="' >$BATCH_DIRS
    . ./tests_perf_remote.list
    let failed=0
    for TEST in $TESTS
    do
      ./test_scripts/$TEST
      if [[ $? != 0 ]]; then
        let failed=failed+1
      else
        SUBMIT_REMOTE=true
      fi
    done
    echo '"' >>$BATCH_DIRS

    if [[ $SUBMIT_REMOTE == true ]]; then
      echo "$(date): Submitting HPC build job ..."
      rsync -a --rsh="ssh" $BATCH_SCRIPT $BATCH_DIRS $HPC:$RUN_DIR_HPC
      ssh $HPC "llsubmit $RUN_DIR_HPC/$BATCH_SCRIPT_NAME"
    fi

    echo "$(date): HPC performance tests finished"
    if [[ $failed == 0 ]]; then
      echo "SUMMARY: All HPC performance tests succeeded"
    else
      echo "SUMMARY: $failed HPC performance tests failed"
    fi
  fi
done
