#!/bin/bash
#------------------------------------------------------------------------------
set -u

#==============================================================================
# Declarations and Environment
declare ThisScript=${0##*/}
declare CmdLine="$0 $*"
declare ThisUser=
declare ThisHost=${HOSTNAME%%.*}

declare -i Debug=${DEBUG:-1}
declare -i i=0
declare -i TestCount=0
declare -i PassCount=0
declare -i FailCount=0

# Version ID Block. Relies on +k filetype modifier.
#------------------------------------------------------------------------------
# shellcheck disable=SC2016
declare VersionID='$Id: //p4-sdp/r26.1.0.BETA/test/test_bash_code_snippets.sh#1 $ $Change: 33444 $'
declare VersionStream=${VersionID#*//}; VersionStream=${VersionStream#*/}; VersionStream=${VersionStream%%/*};
declare VersionCL=${VersionID##*: }; VersionCL=${VersionCL%% *}
declare Version=${VersionStream}.${VersionCL}

# Uppercase stream name in Version for unreleased builds.
[[ "$VersionStream" == r* ]] || Version="${Version^^}"

# ErrorCount is only incremented if the test could not be executed at all
# for some reason, and is independent of pass/fail status of a test.
###declare -i ErrorCount=0

#==============================================================================
# Local Functions.
function msg () { echo -e "$*"; }
function dbg () { [[ "$Debug" -eq 0 ]] || msg "DEBUG: $*"; }
function pass () { msg "PASS: $*"; PassCount+=1; TestCount+=1; }
function fail () { msg "FAIL: $*"; FailCount+=1; TestCount+=1; }
###function errmsg () { msg "\\nError: ${1:-Unknown Error}\\n"; ErrorCount+=1; }

#------------------------------------------------------------------------------
# Bash Code Snippet #1: Regex enabling regex.
#
# The first code snippet tested is the expression to confirm if SSL is enabled
# for a given P4PORT value. That looks like:
#
#   [[ $P4PORT =~ ^ssl[46]*: ]]
#
# The second expression extracts the SSL prefix. That looks like:
#
#   Prefix=${P4PORT%%:*}
#
# The second expression is only guaranteed to work if it is already confirmed
# that SSL is enabled.
#
# See: https://portal.perforce.com/s/article/1180
# Perforce P4 Server IPV6 Support

# Goal: Develop a tight bash regex to accurately detect all variants of
# SSL-enabling P4PORT prefixes, and only SSL-enabled ports (being aware
# of tricksy things like ssltech:1666 that might foil a loose regex).

declare -a PortList
declare -a SSLPort

PortList[i]=ssl:1666
SSLPort[i]=1
i+=1

PortList[i]=ssl::1666
SSLPort[i]=1
i+=1

PortList[i]=ssl:perforce:1666
SSLPort[i]=1
i+=1

PortList[i]=ssltech:1666
SSLPort[i]=0
i+=1

PortList[i]=ssltech:1666
SSLPort[i]=0
i+=1

PortList[i]=ssl64:1666
SSLPort[i]=1
i+=1

PortList[i]=ssl46:1999
SSLPort[i]=1
i+=1

PortList[i]=ssl4:1666
SSLPort[i]=1
i+=1

PortList[i]=ssl6:perforce:2020
SSLPort[i]=1
i+=1

PortList[i]=SSL6:1666 # Port prefixes are case-sensitive; lowercase only.
SSLPort[i]=0
i+=1

PortList[i]=ssl6:PERFORCE:1666 # Hosts are not case-sensitive.
SSLPort[i]=1
i+=1

#==============================================================================
# Main Program

dbg "VersionID:      $VersionID"
dbg "VersionStream:  $VersionStream"
dbg "VersionCL:      $VersionCL"
dbg "Version:        $Version"

ThisUser=$(id -n -u)
msg "Starting $ThisScript version $Version as $ThisUser@$ThisHost on $(date) as:\\n$CmdLine\\n"

#------------------------------------------------------------------------------
# This is for testing bash shell code snippets.
i=0; while [[ $i -lt ${#PortList[@]} ]]; do
   if [[ "${PortList[i]}" =~ ^ssl[46]*: ]]; then
      Prefix=${PortList[i]%%:*}
      if [[ "${SSLPort[i]}" -eq 1 ]]; then
         pass "P4PORT ${PortList[i]} is SSL-enabled (as expected). Prefix: $Prefix"
      else
         fail "P4PORT ${PortList[i]} is SSL-enabled (unexpected result). Prefix: $Prefix"
      fi
   else
      if [[ "${SSLPort[i]}" -eq 1 ]]; then
         fail "P4PORT ${PortList[i]} is not SSL-enabled (unexpected result)."
      else
         pass "P4PORT ${PortList[i]} is not SSL-enabled (as expected)."
      fi
   fi
   i+=1
done

if [[ "$FailCount" -eq 0 ]]; then
   msg "\\nAll $TestCount tests passed."
else
   msg "\\nOf $TestCount tests, $PassCount passed and $FailCount failed."
fi
