#!/bin/bash
#
# Copyright (C) 2015 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Version: 1.3-eng
#
set -o nounset
umask 077

#
# Settings
#
JACK_VERSION=${JACK_VERSION:=4.32.CANDIDATE}
JACK_HOME="${JACK_HOME:=$HOME/.jack-server}"
JACK_CLIENT_SETTING="${JACK_CLIENT_SETTING:=$HOME/.jack-settings}"
TMPDIR=${TMPDIR:=/tmp}
# This is half the timeout since the script will make a second attempt collecting debugs when
# the first attempt fails on connection timeout
JACK_CONNECTION_TIMEOUT=150
JACK_EXTRA_CURL_OPTIONS=${JACK_EXTRA_CURL_OPTIONS:=}
JACK_ASSERTION_ENABLED="${JACK_ASSERTION_ENABLED:=false}"


abort () { exit 255; }


#
# Load client settings
#
if [ -f "$JACK_CLIENT_SETTING" ]; then
  source "$JACK_CLIENT_SETTING"
else
  echo "Cannot find settings at '$JACK_CLIENT_SETTING'" >&2
  abort
fi


JACK_SERVER=${JACK_SERVER:=true}
JACK_MAIN_COMMAND=${JACK_MAIN_COMMAND:="java -Djava.io.tmpdir=$TMPDIR -Dfile.encoding=UTF-8 -XX:+TieredCompilation"}
JACK_REPOSITORY=${JACK_REPOSITORY:=}


#
# If not in server mode, exec jack
#
if [ "$JACK_SERVER" != "true" ]; then
  if [ -z "$JACK_REPOSITORY" ]; then
    echo "Running Jack without Jack server requires definition of JACK_REPOSITORY" >&2
    abort
  fi
  JACK_JAR=$JACK_REPOSITORY/jack-$JACK_VERSION.jar
  if [ ! -r "$JACK_JAR" ]; then
    echo "Jack jar \"$JACK_JAR\" is not readable" >&2
    abort
  fi


  exec $JACK_MAIN_COMMAND -jar $JACK_JAR "$@"
  echo "Cannot succeed to launch Jack without Jack server" >&2
  abort
fi


#
# Prepare compilation
#
JACK_PWD="$PWD"
JACK_EXIT="$TMPDIR/jack-task-$USER-$$-exit"

# Cleanup
trap 'rm -f "$JACK_EXIT" 2>/dev/null;' EXIT

set -o errexit

# Check that we can create temp file for exit status
rm -rf "$JACK_EXIT"
echo "" > "$JACK_EXIT"

#
# Launch the compilation
#

set +o errexit
trap ERR

# put arguments in a non array variable
ARGS=""
for i in "$@"; do
  ARGS="$ARGS $i"
done


CURRENT_CHARSET=$(locale charmap)
if [ -z "$CURRENT_CHARSET" ]; then
  CHARSET_ARGUMENT=
else
  CHARSET_ARGUMENT=";charset=$CURRENT_CHARSET"
fi

# Check base64 availability
BASE64_CHECK=$((echo amFjaw==;echo LXNlcnZlcg==) | base64 --decode 2>&1)

sendRequest() {
RETRY_OPTION=$1
shift

# Launch compilation
exec 3>&1
exec 4>&2
if [ "$BASE64_CHECK" = jack-server ]; then
  HTTP_CODE=$(curl -f $JACK_EXTRA_CURL_OPTIONS $RETRY_OPTION \
       --cert "${JACK_HOME}/client.pem" \
       --cacert "${JACK_HOME}/server.pem" \
       --output >(tee >(sed -n -e 's/^E|\(.*\)$/\1/p' | base64 --decode >&4 ) | tee >(sed -n -e 's/^X|\(.*\)$/\1/p' >>$JACK_EXIT) | sed -n -e 's/^O|\(.*\)$/\1/p' | base64 --decode >&3) \
       --no-buffer --write-out '%{http_code}' --silent --connect-timeout $JACK_CONNECTION_TIMEOUT \
       -X POST \
       -H "Accept: application/vnd.jack.command-out-base64;version=1$CHARSET_ARGUMENT" \
       -F "cli=$ARGS;type=text/plain$CHARSET_ARGUMENT" \
       -F "version=$JACK_VERSION;type=application/vnd.jack.select-exact;version=1" \
       -F "pwd=$JACK_PWD;type=text/plain$CHARSET_ARGUMENT" \
       -F "assert=$JACK_ASSERTION_ENABLED;type=text/plain$CHARSET_ARGUMENT" \
       --noproxy ${SERVER_HOST} \
       https://${SERVER_HOST}:$SERVER_PORT_SERVICE/jack \
       )
else
  HTTP_CODE=$(curl -f $JACK_EXTRA_CURL_OPTIONS $RETRY_OPTION \
       --cert "${JACK_HOME}/client.pem" \
       --cacert "${JACK_HOME}/server.pem" \
       --output >(tee >(sed -n -e 's/^E|\(.*\)$/\1/p' >&4 ) | tee >(sed -n -e 's/^X|\(.*\)$/\1/p' >>$JACK_EXIT) | sed -n -e 's/^O|\(.*\)$/\1/p' >&3) \
       --no-buffer --write-out '%{http_code}' --silent --connect-timeout $JACK_CONNECTION_TIMEOUT \
       -X POST \
       -H "Accept: application/vnd.jack.command-out;version=1$CHARSET_ARGUMENT" \
       -F "cli=$ARGS;type=text/plain$CHARSET_ARGUMENT" \
       -F "version=$JACK_VERSION;type=application/vnd.jack.select-exact;version=1" \
       -F "pwd=$JACK_PWD;type=text/plain$CHARSET_ARGUMENT" \
       -F "assert=$JACK_ASSERTION_ENABLED;type=text/plain$CHARSET_ARGUMENT" \
       --noproxy ${SERVER_HOST} \
       https://${SERVER_HOST}:$SERVER_PORT_SERVICE/jack \
       )
fi
CURL_CODE=$?
exec 3>&-
exec 4>&-

set -o errexit

if [ $CURL_CODE -eq 0 ]; then
  # No problem, let's go
  JACK_CODE=$(cat "$JACK_EXIT")
  exit $JACK_CODE
elif [ $CURL_CODE -eq 7 ]; then
  # Failed to connect
  echo "No Jack server running. Try 'jack-admin start-server'" >&2
  abort
elif [ $CURL_CODE -eq 28 ]; then
  if [ "$RETRY_OPTION" == "" ]; then
    echo "Connection to the Jack server timeout, retrying with debug"
    sendRequest -v $@
  else
    echo "Connection to the Jack server timeout" >&2
    abort
  fi
elif [ $CURL_CODE -eq 35 ]; then
  if [ "$RETRY_OPTION" == "" ]; then
    echo "SSL error when connecting to the Jack server, retrying with debug"
    sendRequest -v $@
  else
    echo "SSL error when connecting to the Jack server. Try 'jack-diagnose'" >&2
    abort
  fi
elif [ $CURL_CODE -eq 58 ]; then
  echo "Failed to contact Jack server: Problem reading ${JACK_HOME}/client.pem. Try 'jack-diagnose'" >&2
  abort
elif [ $CURL_CODE -eq 60 ]; then
  echo "Failed to authenticate Jack server certificate. Try 'jack-diagnose'" >&2
  abort
 elif [ $CURL_CODE -eq 77 ]; then
  echo "Failed to contact Jack server: Problem reading ${JACK_HOME}/server.pem. Try 'jack-diagnose'" >&2
  abort
elif  [ $CURL_CODE -eq 22 ]; then
  # Http code not OK, let's decode and abort
  if [ $HTTP_CODE -eq 400 ]; then
    # 400: Bad request
    echo "Bad request, see server log" >&2
    abort
  else
    # Other
    echo "Internal unknown error ($HTTP_CODE), try 'jack-diagnose' or see Jack server log" >&2
    abort
  fi
else
  echo "Communication error with Jack server ($CURL_CODE). Try 'jack-diagnose'" >&2
  abort
fi
}

sendRequest "" $@
