#!/bin/bash

function configtool_oidc_help() {
  [[ -n "$1" ]] && echo_warning "$1"
  reset_colors
  cat << EOM
${COLOR_YELLOW}The OpenID client for the Configuration tool is applicable only to Maximo Application Suite 9.0 and earlier. Starting in Maximo Application Suite 9.1, the Configuration tool is available with Maximo Application Suite and the OpenID client configuration tool is no longer required.${TEXT_RESET} 

Usage:
  mas oidc [register|unregister|update|-h|--help] [options]
Where ${COLOR_YELLOW}specified${TEXT_RESET} each option may also be defined by setting the appropriate environment variable.
When no options are specified on the command line, interactive-mode will be enabled by default.

${COLOR_YELLOW}1. Cluster credentials${TEXT_RESET}  
Log in to your cluster with your IBMid by using the following method, browse to the OpenShift web console. 
From the dropdown menu in the upper right of the page, click Copy Login Command.
- CLUSTER_TOKEN=sha256~COA8-2Hd6G45rUN0HZLLh47sFByoX8QCC8j92jWB3to  
- CLUSTER_SERVER=https://c130-e.us-south.containers.cloud.ibm.com:32250
example: oc login --token=sha256~COA8-2Hd6G45rUN0HZLLh47sFByoX8QCC8j92jWB3to --server=https://c130-e.us-south.containers.cloud.ibm.com:32250

${COLOR_YELLOW}2. MAS home URL and trust ui prefix${TEXT_RESET}
- MAS_HOME=masdev.home.mobfound1.masdev.suite.maximo.com  
- TRUST_UI_PREFIX="http://localhost:3000, http://localhost:3001"    
${COLOR_YELLOW}Instance id specified if not derived from MAS_HOME url${TEXT_RESET}
- MAS_INSTANCE_ID=mobfnd 

${COLOR_YELLOW}3. Command operation${TEXT_RESET}
### mas oidc register
Register oidc client for config tool.
If client ever registered, it will be deleted firstly. 

${COLOR_YELLOW}### mas oidc unregister${TEXT_RESET}
Unregister oidc client for config tool previously registered.

${COLOR_YELLOW}### mas oidc update${TEXT_RESET}
So far only trust ui prefix is supported to update. Same as register command. 

${COLOR_YELLOW}### mas oidc [-h|--help]${TEXT_RESET}
Show this help message

OAuth Admin Credentials (Optional)
  ${COLOR_YELLOW}OAUTH_ADMIN_USERNAME${TEXT_RESET}.                       If not set, the script will attempt to retrieve this from the {INSTANCE_NAME}-credentials-oauth-admin secret in the mas core namespace
  ${COLOR_YELLOW}OAUTH_ADMIN_PWD${TEXT_RESET}.                            If not set, the script will attempt to retrieve this from the {INSTANCE_NAME}-credentials-oauth-admin secret in the mas core namespace

Cluster Credentials (Required unless both OAUTH_ADMIN_USERNAME and OAUTH_ADMIN_PWD env vars are set):
  -t, --token ${COLOR_YELLOW}CLUSTER_TOKEN${TEXT_RESET}                     Cluster's token
  -s, --server ${COLOR_YELLOW}CLUSTER_SERVER${TEXT_RESET}                   Cluster server

MAS OIDC Information (Required):
  -m, --mas-home ${COLOR_YELLOW}MAS_HOME${TEXT_RESET}                       MAS Home Url
  -p, --ui-prefix ${COLOR_YELLOW}TRUST_UI_PREFIX${TEXT_RESET}               Trust UI prefix to receive OIDC callback

MAS Instance Id (Optional):
  -i, --instance-id ${COLOR_YELLOW}MAS_INSTANCE_ID${TEXT_RESET}             MAS Instance Id
EOM
  [[ -n "$1" ]] && exit 1 || exit 0
}

function configtool_oidc_noninteractive() {
  while [[ $# -gt 0 ]]
  do
    key="$1"
    shift
    case $key in
      -t|--token)
        CLUSTER_TOKEN=$1 && shift
        ;;
      -s|--server)
        CLUSTER_SERVER=$1 && shift
        ;;
      -m|--mas-home)
        MAS_HOME=$1 && shift
        ;;
      -p|--ui-prefix)
        TRUST_UI_PREFIX=$1 && shift
        ;;
      -i|--instance-id)
        MAS_INSTANCE_ID=$1 && shift
        ;;
      *)
        # unknown option
        echo -e "${COLOR_RED}Usage Error: Unsupported option \"${key}\"${TEXT_RESET}\n"
        configtool_oidc_help
        exit 1
        ;;
      esac
  done


  if [[ -z "$OAUTH_ADMIN_USERNAME" || -z "$OAUTH_ADMIN_PWD" ]]; then
    [[ -z "$CLUSTER_TOKEN" ]] && configtool_oidc_help "CLUSTER_TOKEN must be set if either OAUTH_ADMIN_USERNAME or OAUTH_ADMIN_PWD env vars are not provided"
    [[ -z "$CLUSTER_SERVER" ]] && configtool_oidc_help "CLUSTER_SERVER must be set if either OAUTH_ADMIN_USERNAME or OAUTH_ADMIN_PWD env vars are not provided"
  fi
  
  [[ -z "$MAS_HOME" ]] && configtool_oidc_help "MAS_HOME is not set"
  [[ -z "$TRUST_UI_PREFIX" ]] && configtool_oidc_help "TRUST_UI_PREFIX is not set"
}

function configtool_oidc_interactive() {

  echo_h2 "Cluster Credentials"
  echo "Log in to your cluster with your IBMid by using the following method, browse to the OpenShift web console." 
  echo "From the dropdown menu in the upper right of the page, click Copy Login Command."
  echo ""
  prompt_for_input "Cluster Token" CLUSTER_TOKEN && export CLUSTER_TOKEN
  prompt_for_input "Cluster Server" CLUSTER_SERVER && export CLUSTER_SERVER

  echo_h2 "MAS Home Url & OIDC Trust UI Prefix"
  echo "example: masdev.home.mobfound1.masdev.suite.maximo.com"
  prompt_for_input "MAS Home" MAS_HOME && export MAS_HOME
  echo "example: http://localhost:3000, http://localhost:3001"
  prompt_for_input "Trust UI Prefix" TRUST_UI_PREFIX && export TRUST_UI_PREFIX
  echo_h2 "MAS Instance Id (Optional) if specified"
  echo "example: masdev.home.mobfound1.masdev.suite.maximo.com, instance id = mobfound1"
  prompt_for_input "MAS Instance Id" MAS_INSTANCE_ID && export MAS_INSTANCE_ID
}

function configtool_oidc() {
  # take the first parameter off (it will be oidc or configtool-oidc)
  shift
  # second parameter should be register|unregister|update|-h|--help
  if [[ $# -gt 0 ]]; then
    OIDC_OP="$1"
    shift
    case $OIDC_OP in
      -h|--help)
        configtool_oidc_help
        ;;
      register)
        ;;
      unregister)
        ;;
      update)
        ;;
      *)
        # unknown option
        echo -e "${COLOR_RED}Usage Error: Unsupported operation \"${OIDC_OP}\"${TEXT_RESET}\n"
        configtool_oidc_help
        exit 1
        ;;
      esac
  fi
  
  # noneinteractive if more parameters
  if [[ $# -gt 0 ]]; then
    configtool_oidc_noninteractive "$@"
  else
    configtool_oidc_interactive
  fi
  export CLUSTER_TOKEN
  export CLUSTER_SERVER
  export MAS_HOME
  export TRUST_UI_PREFIX
  export MAS_INSTANCE_ID

  # instance name and domain
  echo preparing for $MAS_HOME...
  if [[ -z $MAS_HOME ]]; then
    echo "${COLOR_RED}MAS_HOME must be provided and not empty. sample: export MAS_HOME=\"masdev.home.mobfound1.masdev.suite.maximo.com\"${TEXT_RESET}"
    exit 1
  fi
  MAS_PARTS=(`echo $MAS_HOME | tr "." " "`)
  DOT="."
  DOMAIN_SUFFIX=""
  i=1
  for ELE in "${MAS_PARTS[@]}"
  do
    if [[ $i -eq 3 ]]; then
      INSTANCE_NAME=$ELE
    fi
    if [[ $i -gt 3 && $i -lt ${#MAS_PARTS[@]} ]]; then
      DOMAIN_SUFFIX+=$ELE$DOT
    elif [[ $i -eq ${#MAS_PARTS[@]} ]]; then
      DOMAIN_SUFFIX+=$ELE
    fi
    i=$((i + 1))
  done
  if [[ $i -lt 4 ]]; then
    echo "${COLOR_RED}MAS_HOME is incorrect. sample: \"masdev.home.mobfound1.masdev.suite.maximo.com\"${TEXT_RESET}"
    exit 1
  fi

  # OAUTH information
  CLIENT_CONFIGTOOL="configtoolpkce"
  OAUTH_URL="https://auth.$INSTANCE_NAME.$DOMAIN_SUFFIX/oidc/endpoint/MaximoAppSuite/registration"
  OAUTH_URL_CONFIGTOOL="$OAUTH_URL/$CLIENT_CONFIGTOOL"
  LOGOUT_URL="https://auth.$INSTANCE_NAME.$DOMAIN_SUFFIX/oidc/endpoint/MaximoAppSuite/logout"
  echo "OIDC registration url: $OAUTH_URL"

  if [[ ! -z $MAS_INSTANCE_ID ]]; then
    INSTANCE_NAME=$MAS_INSTANCE_ID
  fi


  # lookup oauth admin credentials from k8s secret if either were not specified as environment vars
  if [[ -z "$OAUTH_ADMIN_USERNAME" || -z "$OAUTH_ADMIN_PWD" ]]; then
    echo Login $CLUSTER_SERVER...
    oc login --token=$CLUSTER_TOKEN --server=$CLUSTER_SERVER
    echo "Entering mas-${INSTANCE_NAME}-core project"
    oc project mas-${INSTANCE_NAME}-core
    if [[ -z "${OAUTH_ADMIN_USERNAME}" ]]; then
      echo "Lookup ${INSTANCE_NAME}-credentials-oauth-admin / oauth-admin-username"
      OAUTH_ADMIN_USERNAME=`oc get secret ${INSTANCE_NAME}-credentials-oauth-admin -o jsonpath="{.data['oauth-admin-username']}" | base64 -d`
    fi
    if [[ -z "${OAUTH_ADMIN_PWD}" ]]; then
      echo "Lookup ${INSTANCE_NAME}-credentials-oauth-admin / oauth-admin-password"
      OAUTH_ADMIN_PWD=`oc get secret ${INSTANCE_NAME}-credentials-oauth-admin -o jsonpath="{.data['oauth-admin-password']}" | base64 -d`
    fi
  fi

  # unregister
  echo checking if $CLIENT_CONFIGTOOL existed
  status_code=`curl -k -w %{http_code} -s -o /dev/null -I --user $OAUTH_ADMIN_USERNAME:$OAUTH_ADMIN_PWD -H 'Content-Type: application/json' $OAUTH_URL_CONFIGTOOL`
  echo "status_code: $status_code"
  echo running $OIDC_OP
  if [[ "$status_code" -eq 200 ]] ; then
    curl --fail -k --user $OAUTH_ADMIN_USERNAME:$OAUTH_ADMIN_PWD \
      -H 'Content-Type: application/json' \
      -X DELETE $OAUTH_URL_CONFIGTOOL || exit $?
    echo ""
    if [[ "$OIDC_OP" == "unregister" ]]; then
      echo "$OIDC_OP" Client $CLIENT_CONFIGTOOL.
      exit 0
    fi
  elif [[ "$status_code" -eq 404 ]] ; then
    if [[ "$OIDC_OP" == "unregister" ]]; then
      echo Client $CLIENT_CONFIGTOOL NOT FOUND, no need "$OIDC_OP".
      exit 0
    fi
  else
    echo Some issue occurred in MAS OIDC server. Please try again later.
    exit 1
  fi

  # trust ui prefix
  echo TRUST_UI_PREFIX: $TRUST_UI_PREFIX
  if [[ -z $TRUST_UI_PREFIX ]]; then
    echo "${COLOR_RED}TRUST_UI_PREFIX must be provided and not empty. sample: export TRUST_UI_PREFIX=\"http://localhost:3000,http://localhost:3001\"${TEXT_RESET}"
    exit 1
  fi
  TRUST_UI_PARTS=(`echo $TRUST_UI_PREFIX | tr "," " "`)
  if [[ ${#TRUST_UI_PARTS[@]} -eq 0 ]]; then
    echo "${COLOR_RED}TRUST_UI_PREFIX is empty, at least define one URL. \"http://localhost:3000\"${TEXT_RESET}"
    exit 1
  fi
  CALLBACK="/auth/callback"
  TRUST_UIS="["
  REDIRECT_UIS="["
  j=1
  for ELE in "${TRUST_UI_PARTS[@]}"
  do
    if [[ j -lt ${#TRUST_UI_PARTS[@]} ]]; then
      TRUST_UIS+="\""$ELE"\","
      REDIRECT_UIS+="\""$ELE$CALLBACK"\","
    else
      TRUST_UIS+="\""$ELE"\""
      REDIRECT_UIS+="\""$ELE$CALLBACK"\""
    fi
    j=$((j + 1))
  done 
  TRUST_UIS+="]"
  REDIRECT_UIS+="]"

  # register or update (the same as register)
  if [[ "$OIDC_OP" == "register" || "$OIDC_OP" == "update" ]]; then
    echo "$OIDC_OP" Client $CLIENT_CONFIGTOOL.
    curl --fail -k --user $OAUTH_ADMIN_USERNAME:$OAUTH_ADMIN_PWD \
    -H 'Accept: application/json' \
    -H 'Content-type: application/json' \
    -X POST $OAUTH_URL \
    -d @<(cat <<EOF
{
"client_id": "$CLIENT_CONFIGTOOL",
"publicClient": true,
"proofKeyForCodeExchange": true,
"token_endpoint_auth_method":"client_secret_basic",
"scope":"openid profile email general",
"grant_types":[
    "authorization_code",
    "client_credentials",
    "implicit",
    "refresh_token",
    "urn:ietf:params:oauth:grant-type:jwt-bearer"
],
"response_types":[
    "code",
    "token",
    "id_token token"
],
"application_type":"web",
"subject_type":"public",
"post_logout_redirect_uris": ["$LOGOUT_URL"],
"preauthorized_scope":"openid profile email general",
"introspect_tokens": true,
"trusted_uri_prefixes": $TRUST_UIS,
"redirect_uris": $REDIRECT_UIS
}
EOF
) || exit $?
  fi
}