#!/bin/bash


#TODO:
#  - move scripts from jenkins to petsc repo
#  - Add descriptions to web pages


OPTIND=1
httpprotocol=http
jenkinsserver=petsc.mcs.anl.gov
jenkinsport=8080
publishurl="http://ftp.mcs.anl.gov/pub/petsc/nightlylogs/jenkins"
httpurl=${httpprotocol}://${jenkinsserver}:${jenkinsport}
sshserver=login.mcs.anl.gov                   # machine from which you can access the Jenkins server
username=$JENKINS_USERNAME                    # your user name on the sshserver machine
email=$JENKINS_EMAIL
branch=`git symbolic-ref -q --short HEAD 2>/dev/null`
configoptions=""
silent="yes"
status=""
results=""
testall="\&testall=false"
buildlist=""
quickcover=""
debugging=debugging
compiler=gnu
clanguage=C
precision=double
label=linux64
integersize=int32
scalartype=real
tests=test


if ! options=$(getopt -o hb:m:o:qt:u:v -l help,branch:,mail:,clanguage:,compiler:,debugging:,arch:,precision:,scalartype:,integersize: -- "$@")
then
    exit 1
fi
eval set -- "$options"

while [ $# -gt 0 ]
do
  case $1 in
    -h|--help)
      echo "sendToJenkins script. Sends a job to the jenkins server, "
      echo "${httpurl}. Job output (configure.log, make.log, test.log) "
      echo "will be emailed to given address (use -m or set JENKINS_EMAIL"
      echo "variable) and will be available at "
      echo "  ${publishurl}."
      echo
      echo "Options: -h <help>"
      echo "         -b <branch of PETSc to test>       -- default is your current working branch (now ${branch})"
      echo "         -m <address to mail to>            -- required. or environmental variable JENKINS_EMAIL"
      echo "            Use 'none' if no email desired"
      echo "         -o <configure options>             -- default is empty"
      echo '            Example: -o "--download-mpich=1"'
      echo "         -q                                 -- quickcover:"
      echo "            Run a particular set of tests:"
      echo "              opensolaris sun C++ nodebug complex int64 double"
      echo "              linux64 gnu C debug real int32 __float128"
      echo "              linux64 intel C debug real int64 double"
      echo "              osx C++ debug real int32 single" 
      echo "         -t                                 -- test(default), alltest, or a particular test"
      echo "                                            (e.g. src/snes/examples/tests:runex12f)"
      echo "         -u <username on login.mcs.anl.gov> -- default is empty or environmental variable JENKINS_USERNAME"
      echo "         -v                                 -- verbose"
      echo "         --arch=(osx,opensolaris,linux64,all)    default=${label}"
      echo "         --debugging=(debugging,nodebugging,all) default=${debugging}"
      echo "         --clanguage=(C,C++,all)                 default=${clanguage}"
      echo "         --compiler=(gnu,intel,clang,all)        default=${compiler}"
      echo "         --precision=(single,double,__float128,all) default=${precision}"
      echo "         --integersize=(int32,int64,all)         default=${integersize}"
      echo "         --scalartype=(real,complex,all)         default=${scalartype}"
      exit 0
      ;;
    -b|--branch)
      branch=$2
      shift  ;;
    -m|--mail)
      email=$2
      shift  ;;
    -o|--options)
     configoptions=$2
     configoptions=${configoptions// /%20}
     configoptions=${configoptions//=/%3D}
     configoptions="\&configure_options=${configoptions}"
     shift ;;
    -q)
        quickcover="quickcover"
        ;;
    -u|--username)
        username=$2
        shift ;;
    -t)
        tests=$2;
        shift ;;
    -v)
     silent=yes
     ;;
    --arch)
      label=$2;
      shift ;;
    --clanguage)
        clanguage=$2;
        if [[ "${clanguage}" != C && "${clanguage}" != C++ && "${clanguage}" != all ]]; then
            echo "clanguage must be C, C++, or all"
            exit 1
        fi
        shift ;;
    --debugging)
        debugging=$2;
        if [[ "${debugging}" != debugging && "${debugging}" != nodebugging && "${debugging}" != all ]]; then
            echo "debugging must be debugging, nodebugging, or all"
            exit 1
        fi
        shift;;
    --precision)
        precision=$2;
        echo ${precision}
        if [[ "${precision}" != single && "${precision}" != double && "${precision}" != __float128 && "${precision}" != all ]]; then
            echo "precision must be single, double, __float128, or all"
            exit 1
        fi
        shift;;
    --scalartype)
        scalartype=$2;
        if [[ "${scalartype}" != real && "${scalartype}" != complex && "${scalartype}" != all ]]; then
            echo "scalartype must be real, complex, or all"
            exit 1
        fi
        shift;;
    --integersize)
        integersize=$2;
        if [[ "${integersize}" != int32 && "${integersize}" != int64 && "${integersize}" != all ]]; then
            echo "scalartype must be int32, int64, or all"
            exit 1
        fi
        shift;;
    (--) shift; break;;
    (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
    (*) break;;

  esac
  shift
done
if [[ "${silent}" == no ]]; then
  echo label=${label}
  echo clanguage=${clanguage}
  echo debugging=${debugging}
  echo precision=${precision}
  echo scalartype=${scalartype}
  echo integersize=${integersize}
  echo quickcover=${quickcover}
  echo email=${email}
fi


if [ "${branch}x" == "x" ]; then
  branch="next"
  echo "No current git branch detected, testing 'next'"
else
    echo "Testing git branch ${branch}. Use -b option to change."
fi


if [ -z ${username} ]; then
  sshurl=${sshserver}
else
  sshurl=${username}@${sshserver}
fi;


if [[ "${quickcover}" == quickcover ]]; then
    job=PETSc-quickcover
    branchparam="branch=${branch}"
else
    if [[ "${branch}" == next || "${branch}" == master || "${branch}" == maint ]]; then
        job=PETSc-${branch}
        branchparam=""
    else
        job=PETSc-branch
        branchparam="branch=${branch}"
    fi
fi

# set up connection through named proxy
command="ssh -M -S jenkins-proxy -fnNT ${sshurl}"
if [[ "${silent}" == "no" ]]; then
   echo ${command}
   ${command}
else
   ${command} 2> /dev/null
fi

if [ "x${email}" == "x" ]; then
  mailto=""
else
  mailtoparam="\&mailto=${email}"
fi

if [[ "${silent}" == "no" ]]; then
  echo "trying: ssh -S jenkins-proxy ${sshserver} curl -s ${httpurl}/job/${job}/api/json"
fi

bn=`ssh -S jenkins-proxy ${sshserver} curl -s ${httpurl}/job/${job}/api/json | python -c 'import sys,json; print json.load(sys.stdin)["nextBuildNumber"]'`
if [[ "${bn}x" == "x" ]]; then
    echo "Failed to get nextBuildNumber"
    exit 0
fi

tag=`date +%s`.${bn}

if [[ "${silent}" == "no" ]]; then
  echo "job = ${job}, next build number = ${bn}"
  echo tag = ${tag}
fi


command="ssh -S jenkins-proxy ${sshurl} curl -s -X POST ${httpurl}/job/${job}/buildWithParameters?${branchparam}${mailtoparam}\&id_tag=${tag}\&debuggingTests=${debugging}\&clanguageTests=${clanguage}\&precisionTests=${precision}\&scalarTypeTests=${scalartype}\&integerSizeTests=${integersize}\&compilerTests=${compiler}\&testname=${tests}"
if [[ "${silent}" == "no" ]]; then
    echo "${command}"
fi
${command}

sleep 10
if [[ "${silent}" == "no" ]]; then
    echo "trying: ssh -S jenkins-proxy ${sshserver} curl -s ${httpurl}/job/${job}/${bn}/api/json?depth=1"
fi

test_id=`ssh -S jenkins-proxy ${sshserver} curl -s ${httpurl}/job/${job}/${bn}/api/json?depth=1 | python -c $'import sys,json; pars=json.load(sys.stdin)["actions"][0]["parameters"];\nfor p in pars:\n  if p["name"].find("id_tag")>=0:\n     print p["value"]'`

if [[ ${test_id} == ${tag} ]]; then
    echo "build number is confirmed ${bn}"
else
    echo "warning: build number may not be ${bn}"
fi


# Close proxy connection
command="ssh -S jenkins-proxy -O exit ${sshurl}"
if [[ "${silent}" == "no" ]]; then
    echo "${command}"
    ${command}
else
    ${command} 2> /dev/null
fi

echo
echo "Submission to Jenkins complete."
if [[ "x${email}" == "x" ]]; then
  echo "Note: No email address give. Use -m <email> or set JENKINS_EMAIL"
else
  echo "Jenkins will email results to ${email}"
fi


echo
echo "Submission can be tracked at ${httpurl}/job/${job}/${bn}"
echo "for build status, visit above url"
echo
echo "It may be necessary to tunnel through to web page, you can either"
echo "set up a SOCKS proxy (and the configure browser) with"
echo "ssh -N -D 10800 ${username}@${sshserver}   (10800 can be any open port number)"
echo
echo "Or directly forward https traffic from localhost to jenkins host with"
echo "ssh -N -L 10800:${jenkinsserver}:443 ${username}@${sshserver}"
if [[ "${quickcover}x" == "x" ]]; then
    echo "and use https://localhost:10800/job/PETSc-${branch}/${bn}"
    echo
    echo "When completed, results will be posted to ${publishurl}/PETSc-${branch}/${bn}"
else
    echo "and use https://localhost:10800/job/PETSc-quickcover/${bn}"
    echo
    echo "When completed, results will be posted to ${publishurl}/PETSc-quickcover/${bn}"
fi
echo

