#!/bin/bash
# @description replace a directive occurrence in all the Rudder rules by another directive.
# @man replace a directive occurrence in all the Rudder rules by another directive.
# @man +
# @man *Arguments*:
# @man +
# @man *-o*: old directive id
# @man +
# @man *-n*: new directive id
# @man +
# @man *-c*: raw color mode, all output are non-colored text
# @man +
# @man *-i*: verbose mode, display more detailed information of the execution

. "${BASEDIR}/../lib/common.sh"
. "${BASEDIR}/../lib/api_call.sh"

DISPLAY_COMMAND=false

while getopts "iIvdc:o:n:" opt; do
  case $opt in
    i|I|v|d)
      DISPLAY_COMMAND=true
      ;;
    o)
      OLD_DIRECTIVE="${OPTARG}"
      ;;
    n)
      NEW_DIRECTIVE="${OPTARG}"
      ;;
    c)
      clear_colors
      ;;
  esac
done
# to keep the argument as $1
shift  $((OPTIND-1))

if [[ -z ${OLD_DIRECTIVE} || -z ${NEW_DIRECTIVE} ]]
then
  echo "Usage: rudder server directive-replace [-iIvd] [-c] -o <old-directive> -n <new-directive>"
  exit 1
fi

echo "DIRECTIVE ${OLD_DIRECTIVE} will be replaced by ${NEW_DIRECTIVE}"
echo ""

# Find the rules using the old directive
RULES=$(rudder_api_call "/rules" "GET" "" "${DISPLAY_COMMAND}" | jq -r " .data.rules[] | select(.directives[] | contains(\"${OLD_DIRECTIVE}\")) | {\"id\":.id, \"displayName\":.displayName, \"directives\":.directives}")

echo "Directives ${OLD_DIRECTIVE} will be replaced by ${NEW_DIRECTIVE} in the following rules:"
printf "${RULES}\n\n"

# Adding the new directive in the local JSON with jq
RULES=$(echo "${RULES}" | jq '.directives |= (. +["'${NEW_DIRECTIVE}'"] |unique)')
# Removing the old directive in the local JSON with jq
RULES=$(echo "${RULES}" | jq '.directives |= (. -["'${OLD_DIRECTIVE}'"] |unique)')
echo ""
if [ -z "${RULES}" ];
then
  printf "${RED}  No rules found using the directive ${BLUE}${OLD_DIRECTIVE}${RED}, aborting.${NORMAL}\n\n"
else
  while IFS= read
  do
      echo "Treating $REPLY"
      # Adding the new directive
      DIRECTIVES=$( echo ${RULES} | jq -r 'select(.id=="'${REPLY}'") |.directives')
      result=$(rudder_api_call "/rules/$REPLY" "POST" "-d '{\"directives\": $DIRECTIVES}'" "${DISPLAY_COMMAND}")
      code=$?

      #Looking for old directive
      old_result=$(rudder_api_call "/rules/$REPLY" "GET" "" "${DISPLAY_COMMAND}" | jq ".data.rules[] | select(.directives[] | contains(\"${OLD_DIRECTIVE}\")) | {\"id\":.id, \"displayName\":.displayName, \"directives\":.directives}")
      if ! [ -z "${old_result}" ];
      then
        printf "${RED} Unexpected old directive found ${old_result}${NORMAL}\n\n"
      fi

      #Looking for new directive
      new_result=$(rudder_api_call "/rules/$REPLY" "GET" "" "${DISPLAY_COMMAND}" | jq ".data.rules[] | select(.directives[] | contains(\"${NEW_DIRECTIVE}\")) | {\"id\":.id, \"displayName\":.displayName, \"directives\":.directives}" )
      if  $DISPLAY_COMMAND ;
      then
        printf "${GREEN} New directive found ${new_result}${NORMAL}\n\n"
      fi

      if [ ${code} -eq 0 ] && [ -z "${old_result}" ]
      then
        printf "  ${GREEN}ok${NORMAL}: Add new directive ${NEW_DIRECTIVE} and removing old directive ${OLD_DIRECTIVE} to rule ${REPLY}\n"
      else
        printf "  ${RED}error${NORMAL}: Could not add new directive ${NEW_DIRECTIVE} and remove ${OLD_DIRECTIVE} to rule ${REPLY} \n"
        echo "  ${result}"
        exit 1
      fi
  done <<< "$(echo ${RULES} | jq -r '.id')"
fi
