#!/bin/bash
########################################################################
#  (@)sql.sh
#
#  Copyright 2014 by Oracle Corporation,
#  500 Oracle Parkway, Redwood Shores, California, 94065, U.S.A.
#  All rights reserved.
#
#  This software is the confidential and proprietary information
#  of Oracle Corporation.
#
# NAME	sql
#
# DESC 	This script starts SQL CL.
#
# AUTHOR bamcgill
#
# MODIFIED
#   bamcgill    21/03/2014  Created
#   bamcgill    18/07/2014  Simplified classpaths and args
#   bamcgill    11/12/2014  Renamed script and contents
#   bamcgill    16/01/2015  Renamed script and contents
#   bamcgill    05/02/2015  Added STD_ARGS for headless and other args
#   cdivilly    12/02/2015  Locate home folder via symlinks
#   bamcgill    10/06/2015  Quote jarfiles for dirs with spaces
#   bamcgill    02/10/2015  Adding specific JAVA_HOME for ADE dev users
#   totierne    02/10/2015  use -cp instead of JARFILE to add ojdbc6 
#   bamcgill    14/10/2015  switch Cygwin settings so Cygwin Term will work
#   totierne    16/10/2015  add classpath to allow times ten jars
#   bamcgill    17/10/2015  Cleaning up bootstrap to call single java 
#                           implementation with pruned args.
#   totierne    12/05/2016  added $OH/lib to $LD_LIBRARY_PATH when $OH 
#   bamcgill    12/05/2016  adding -cleanup to args 
#   bamcgill    29/06/2016  Added more checks around JAVA_HOME settings 
#   bamcgill    04/07/2016  Using the ADE RDBMS JDK if it exists.
#   jmcginni    23/08/2016  Grab Proxy info on Mac, KDE, Gnome
#   bamcgill    04/11/2016  Added all jars to classpath and pointed cobertura
#                           ser file for running.
#   bamcgill    17/11/2016  Added $OH/jdk as java location if JAVA_HOME not set
########################################################################


AddVMOption()
{
  APP_VM_OPTS[${#APP_VM_OPTS[*]}]="$*"
}

#
# if we are in ADE environement, check for JAVA_HOME
#
function checkADE {
	#
	# Resolve java path for development builds
	#
	if [ -d "/ade_autofs/" ] ||  [ -n "${ADE_VIEW_ROOT+1}" ]; 
	 then
	 if  [  "m$JAVA_HOME" != "m" ]; then #Only set this if it is not already there.
	   if  [ ! -d "$JAVA_HOME" ]; then #and it doesnt exists.... 
	   	 if  [  "m$ORACLE_HOME" != "m" ]; then 
	   	   if  [ -d "$ORACLE_HOME/jdk/jre" ]; then
	         JAVA_HOME=$ORACLE_HOME/jdk/jre
	         PATH=$JAVA_HOME/bin:$PATH
	        fi
	      fi 
	   fi
     else 
       if  [  "m$ORACLE_HOME" != "m" ]; then 
	   	    if  [ -d "$ORACLE_HOME/jdk/jre" ]; then
	           JAVA_HOME=$ORACLE_HOME/jdk/jre
	            PATH=$JAVA_HOME/bin:$PATH
	        fi 
   	   fi
     fi
     export SQLPLUS_CLASSIC=true   
   fi
}

#
# set up the main arguments for java.
#
function setupArgs {
	#
	# Standard JVM options which are always used
	#
	AddVMOption -Djava.awt.headless=true 
	AddVMOption -Dapple.awt.UIElement=true
	AddVMOption -Xss10M
}

#
# Set SQLHOME to be canonical paths
#
function setupSQLHome {
	#
	# resolve the folder where this script is located, traversing any symlinks
	#
	PRG="$0"
	# loop while $PRG is a symlink
	while [ -h "$PRG" ] ; do
	  # figure out target of the symlink
	  ls=`ls -ld "$PRG"`
	  link=`expr "$ls" : '.*-> \(.*\)$'`
	  # traverse to the target of the symlink
	  if expr "$link" : '/.*' > /dev/null; then
	  PRG="$link"
	  else
	  PRG=`dirname "$PRG"`"/$link"
	  fi
	done
	
	#
	# SQLHOME is where we live.  Lets get an exact address.
	# sql script is in ${SQL_HOME}/bin so lets check above and get the 
	# canonical path for that
	#
	SQL_HOME=`dirname "$PRG"`/..
	export SQL_HOME=`cd "${SQL_HOME}" > /dev/null && pwd`
	
	# If you have downloaded a jre, dropping it into sqlcl as jre will make it first in line
	if [ -d "$SQL_HOME/jre/" ]; then
	 JAVA_HOME=$SQL_HOME/jre/
	 PATH=$JAVA_HOME/bin:$PATH
	fi

}

#
# Setup classpath depending on where we are
#
function setupClasspath {
	#
	# If we are in an ORACLE_HOME, then we want to try to use the jdbc
	# drivers in there.
	# Here we are frontloading the Oracle JDBC jars. We are not version
	# checking at this stage. 
	#
	if test  "m$ORACLE_HOME" = "m" 
	then
	  CPLIST="$SQL_HOME/lib/oracle.sqldeveloper.sqlcl.jar:$SQL_HOME/lib/*:$CLASSPATH"
	else
	  # where ORACLE_HOME points to ordinary ORACLE_HOME or 
	  # INSTANT_CLIENT (or use shipped with sqlcl ojdbc8.jar)
	  CPLIST="$ORACLE_HOME/jdbc/lib/ojdbc8.jar:$ORACLE_HOME/ojdbc8.jar:$ORACLE_HOME/jdbc/lib/ojdbc7.jar:$ORACLE_HOME/ojdbc7.jar:$ORACLE_HOME/jdbc/lib/ojdbc6.jar:$ORACLE_HOME/ojdbc6.jar:$SQL_HOME/lib/oracle.sqldeveloper.sqlcl.jar:$CLASSPATH"  
	  #Patch for oci jdbc
	  if [ -d "$SQL_HOME/thick/" ]; then
	   CPLIST="$SQL_HOME/thick/ojdbc8.jar:$CPLIST"
	   export LD_LIBRARY_PATH=$SQL_HOME/thick:$LD_LIBRARY_PATH
	  else
	   export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$ORACLE_HOME:$LD_LIBRARY_PATH
	  fi
	fi
	 
	#
	# Lets look for jars in the extensions
	# directory under lib.  These will be loaded
	# at startup as well.
	#
	if  [ -f $SQL_HOME/cobertura.ser ]
	then
	#Setup cobertura classpath
		COBERTURA=$SQL_HOME/lib/cobertura-2.1.1.jar
		INSTRUMENTED_CLASSES=$SQL_HOME/lib/oracle.dbtools-common.jar:$SQL_HOME/lib/oracle.sqldeveloper.sqlcl.jar
		CPLIST=$COBERTURA:$INSTRUMENTED_CLASSES:$SQL_HOME/lib/*:$CLASSPATH
		AddVMOption -Dnet.sourceforge.cobertura.datafile=$SQL_HOME/cobertura.ser
	fi
}
#
# Do you use cygwin?  Lets see and make the classpath right
#
function checkCygwin {

#
# Ok, now we have a classpath, lets make sure it works with Cygwin too.
#
	#
	# Check for Cygwin
	#
	cygwin=false
	case `uname` in
		CYGWIN*) cygwin=true;;
	esac
	
	#
	# If its Cygwin, then convert the classpath to posix style.
	# Convert the terminal to something that the Cygwin terminal 
	# will understand and force jline to use a unix terminal as
	# cygwin reports TTY style badly
	if $cygwin; then
	 CPLIST=$(cygpath -pw "$CPLIST") 
	 stty -icanon min 1 -echo > /dev/null 2>&1
	 stty icanon echo > /dev/null 2>&1
	 CYGWIN=-Djline.terminal=jline.UnixTerminal
	fi
}

#
# Check if JAVA_HOME is set and if so, make sure we run the java there.
#
function checkJavaLocation {

#Test for JAVA_HOME settings.  If it is set, we want to use it over and above what /usr/bin/java says
JAVA=java
 if  [  "m$JAVA_HOME" != "m" ]; then 
   if  [ -d "$JAVA_HOME" ];  
   then 
 	JAVA="$JAVA_HOME/bin/java";
 	fi
  fi
  if [  "m$ORACLE_HOME" != "m" ]; then
    #if there is a jdk in the Oracle home and JAVA_HOME is not set
     if  [ -d "$ORACLE_HOME/jdk" ] && [  "m$JAVA_HOME" == "m" ];
     then
       JAVA_HOME="$ORACLE_HOME/jdk";
       JAVA=$JAVA_HOME/bin/java
     fi
   fi  
}

#
# Check for proxies
#

# The following HTTP proxy-related code taken from NetBeans nbexec script.
DetectSystemHttpProxySetting()
{

    unset http_proxy_tmp

    if [ `uname` = Darwin ] ; then
	detect_macosx_proxy
    else
	if [ "$KDE_FULL_SESSION" = "true" ] ; then
            detect_kde_proxy
	else
            if [ ! -z "$GNOME_DESKTOP_SESSION_ID" ] ; then
        	detect_gnome_proxy
            fi
	fi
    fi

    # fall back to the environment-defined http_proxy if nothing found so far
    if [ -z "$http_proxy_tmp" ]; then
	http_proxy_tmp=$http_proxy
    fi

    if [ ! -z "$http_proxy_tmp" ] ; then
    #	jargs="-Dnetbeans.system_http_proxy=\"$http_proxy_tmp\" -Dnetbeans.system_http_non_proxy_hosts=\"$http_non_proxy_hosts\" $jargs"
	    AddVMOption -Ddbtools.system_http_proxy=$http_proxy_tmp
	    AddVMOption -Ddbtools.system_http_non_proxy_hosts=$http_non_proxy_hosts
    fi

    if [ ! -z "$socks_proxy_tmp" ] ; then
    #	jargs="-Dnetbeans.system_socks_proxy=\"$socks_proxy_tmp\" $jargs"
	    AddVMOption -Ddbtools.system_socks_proxy=$socks_proxy_tmp
    fi

}

detect_system_proxy () {
    if [ ! -z "$http_proxy" ]; then
        http_proxy_tmp=$http_proxy
    fi
    return 0
}

detect_gnome_proxy () {
    gconftool=/usr/bin/gconftool-2
    if [ -x  $gconftool ] ; then
        proxy_mode=`$gconftool --get /system/proxy/mode 2>/dev/null`
        if [ "$proxy_mode" = "manual" ] ; then
            http_proxy_host=`$gconftool --get /system/http_proxy/host 2>/dev/null`
            http_proxy_port=`$gconftool --get /system/http_proxy/port 2>/dev/null`
            http_proxy_tmp=$http_proxy_host:$http_proxy_port
            http_non_proxy_hosts=`$gconftool --get /system/http_proxy/ignore_hosts 2>/dev/null`
            if [ $? ] ; then
                http_non_proxy_hosts=`echo $http_non_proxy_hosts | /bin/sed 's/\]//'`
            fi
            socks_proxy_host=`$gconftool --get /system/proxy/socks_host 2>/dev/null`
            socks_proxy_port=`$gconftool --get /system/proxy/socks_port 2>/dev/null`
            socks_proxy_tmp=$socks_proxy_host:$socks_proxy_port

            return 0
        else
            if [ "$proxy_mode" = "none" ] ; then
                detect_system_proxy
                if [ -z "$http_proxy_tmp" ]; then
                    http_proxy_tmp="DIRECT"
                fi
                return 0
            else
                if [ "$proxy_mode" = "auto" ] ; then
                    detect_system_proxy
                    pac_file=`$gconftool --get /system/proxy/autoconfig_url 2>/dev/null`
                    if [ ! -z "$pac_file" ]; then
                        http_proxy_tmp="PAC "$pac_file
                    fi
                    return 0
                fi
            fi
        fi
    fi
    return 1
}

detect_kde_proxy () {
    kioslaverc="${HOME}/.kde/share/config/kioslaverc"
    if [ -f $kioslaverc ] ; then
        if /bin/grep 'ProxyType=1' "$kioslaverc" >/dev/null 2>&1; then
            http_proxy_tmp=`/bin/grep 'httpProxy=http://' "$kioslaverc"`
            if [ $? ] ; then
                http_proxy_tmp=`echo $http_proxy_tmp | /bin/sed 's/httpProxy=http:\/\///'`
                return 0
            fi
            http_non_proxy_hosts=`/bin/grep 'NoProxyFor=' "$kioslaverc"`
            if [ $? ] ; then
                http_non_proxy_hosts=`echo $http_non_proxy_hosts | /bin/sed 's/NoProxyFor=//'`
            fi
        else
            if /bin/grep 'ProxyType=0' "$kioslaverc" >/dev/null 2>&1; then
                detect_system_proxy
                if [ -z "$http_proxy_tmp" ]; then
                    http_proxy_tmp="DIRECT"
                fi
                return 0
            else
                if /bin/grep 'ProxyType=2' "$kioslaverc" >/dev/null 2>&1; then
                    pac_file=`grep "Proxy Config Script=" $kioslaverc  | cut -f 2 -d =`
                    http_proxy_tmp="PAC "$pac_file
                    return 0
                fi
            fi
        fi
    fi
    return 1
}

detect_macosx_proxy () {
    if [ ! -x /usr/sbin/scutil ] ; then
	return 1
    fi

    scutil_out=/tmp/nb-proxy-detection.$$
    cat <<EOF | /usr/sbin/scutil > ${scutil_out}
open
show State:/Network/Global/Proxies
close
EOF

    if /usr/bin/grep "ProxyAuto.*: *1" ${scutil_out} >/dev/null 2>&1; then
        if  /usr/bin/grep "ProxyAutoConfigEnable.*: *1" ${scutil_out} >/dev/null 2>&1; then
            http_proxy_tmp="PAC `/usr/bin/grep ProxyAutoConfigURLString ${scutil_out} | /usr/bin/awk 'END{print $3}'`"
            rm ${scutil_out}
            return 0
        fi

        rm ${scutil_out}
        return 1
    fi

    if /usr/bin/grep "HTTPEnable *: *1" ${scutil_out} >/dev/null 2>&1; then
	http_proxy_host=`/usr/bin/grep HTTPProxy ${scutil_out} | /usr/bin/awk 'END{print $3}'`
	http_proxy_port=`/usr/bin/grep HTTPPort ${scutil_out} | /usr/bin/awk 'END{print $3} '`
        http_proxy_tmp=$http_proxy_host:$http_proxy_port
        rm ${scutil_out}
        return 0
    fi

    http_proxy_tmp="DIRECT"
    rm ${scutil_out}
    return 0
}

#
# if we have a debug flag, we want to remove it, but also tell java
# to switch on debugging. Hence we'll need a new array to pass to java
#
function processArgs {
 id=0;
 ISDEBUG=0;
 for var
 do
    if [ $var != '-debug' ]
    then
      ARGS[id]=$var;
      let id++;
    else
      ISDEBUG=1;
    fi
 done
 if [ $ISDEBUG == 1 ]
 then
    DEBUG="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000"
 else
    DEBUG=""
 fi
}

#
# Run the tool.
#
function run {
 if  [  "m$DEBUG" != "m" ]; then 
   echo "JAVA=$JAVA"
   echo "JAVA_OPTS=${APP_VM_OPTS[@]}"
   echo "DEBUG=$DEBUG"
   echo "CPLIST=$CPLIST"
   echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
   echo "$JAVA  $CUSTOM_JDBC $CYGWIN "${APP_VM_OPTS[@]}" -client $DEBUG -cp "$CPLIST" oracle.dbtools.raptor.scriptrunner.cmdline.SqlCli "
   
 fi
$JAVA  $CUSTOM_JDBC $CYGWIN "${APP_VM_OPTS[@]}" -client $DEBUG -cp "$CPLIST" oracle.dbtools.raptor.scriptrunner.cmdline.SqlCli "$@"
}

#
# This is where we start SQLcl properly. We're going to process the arguments
# sent in, build our classpath, build our JVM options, prepare the terminal
# and kick off the main.
#
function bootStrap {
	echo "$@" | grep '\-debug' > /dev/null 2>&1 
	if test "m$?" != "m0"
	then
		#if it is not debug we can pass the arguments straight through 
		#runNormalArgs
		run "$@"
	   exit $?
	else
		# Process the arguments and see if we have are in debug mode
		processArgs "$@"
		#
		# if you want to see what is getting passed, uncomment the next line
		#echo "after process args ${ARGS[@]}"
		#runModifiedArgs
		run ${ARGS[*]}
	fi
}


checkADE
setupArgs
setupSQLHome
setupClasspath
checkJavaLocation
DetectSystemHttpProxySetting
#Lets get your freak on
bootStrap "$@"
