#!/bin/bash
LOG=/tmp/sdk.log

APP_NAME=$(basename $(dirname $(dirname $0)))
HTTP_STATUS=200
ERROR_MESSAGE="Unknown error"

decode() {
  echo -e "$(sed 's/+/ /g;s/%/\\x/g;')"
}

get_resources() {
  eval $QUERY_STRING # GET "name" sent from request
  if [ -z "$name" ]; then # name was not passed ( get all resources )
    RESOURCES=$(xmlstarlet sel -t -m "webresources/protected/resource" -v "@name" -o "," -n "$WEB_XML")
  else # get resource with provided "$name"
    name=$(echo $name | decode)
    RESOURCES=$(xmlstarlet sel -t -m "webresources/protected/resource[@name='$name']" -v "@name" -o "," -n "$WEB_XML")
    if [ -z "$RESOURCES" ]; then # no resources with provided name
      {
        HTTP_STATUS=500
        ERROR_MESSAGE="Resource with '$name' name not found."
        return 51
      }
    fi
  fi

  if [ -z "$RESOURCES" ]; then # no resources
    {
      HTTP_STATUS=500
      ERROR_MESSAGE="No resources found."
      return 52
    }
  fi

  if [ -z "$name" ]; then # if get all create array
    RESOURCES_JSON="["
  fi
  # for all resources
  for RESOURCE in $(echo "$RESOURCES" | tr ',' '\n'); do
    RESOURCES_JSON="$RESOURCES_JSON {\"name\": \"$RESOURCE\", "                                                                  # open resource object
    RESOURCE_ROLES=$(xmlstarlet sel -t -m "webresources/protected/resource[@name='$RESOURCE']" -v "@roles" -o "," -n "$WEB_XML") # get resource roles
    if [ -z $RESOURCE_ROLES ]; then # empty roles
      RESOURCES_JSON="$RESOURCES_JSON \"roles\":[]"
    else # add all roles to JSON string
      ROLE_COUNT=0
      RESOURCES_JSON="$RESOURCES_JSON \"roles\":["
      for role in $(echo "$RESOURCE_ROLES" | tr ',' '\n'); do
        if [ "$ROLE_COUNT" -eq "0" ]; then
          RESOURCES_JSON="$RESOURCES_JSON \"$role\""
        else
          RESOURCES_JSON="$RESOURCES_JSON , \"$role\""
        fi
        ROLE_COUNT=$(expr $ROLE_COUNT + 1)
      done
      RESOURCES_JSON="$RESOURCES_JSON ]" # close roles array
    fi
    RESOURCES_JSON="$RESOURCES_JSON }," # close resource object
  done

  if [ -z "$name" ]; then # if get all close array
    RESOURCES_JSON="${RESOURCES_JSON%?} ]" # remove last coma and close array
  else
    RESOURCES_JSON="${RESOURCES_JSON%?}" # remove last coma
  fi
  return 0

}

update_resources() {
  if [ "$CONTENT_LENGTH" -gt 0 ]; then
    POST_DATA=$(cat -)
  fi
  NAME=$(echo $POST_DATA | jq -r '.name')
  JSON_ROLES=$(echo $POST_DATA | jq -r '.roles')
  if [ -z "$NAME" ]; then
    {
      HTTP_STATUS=400
      ERROR_MESSAGE="Invalid request."
      return 1
    }
  fi
  [[ $(echo $POST_DATA | jq -e 'has("name")') == "false" ]] && {
    HTTP_STATUS=400
    ERROR_MESSAGE="Parameter 'name' is required."
    return 2
  }

  RESOURCES=$(xmlstarlet sel -t -m "webresources/protected/resource[@name='$NAME']" -v "@name" -n "$WEB_XML")
  for role in $(echo "${JSON_ROLES}" | jq -r '.[]'); do
    ROLES="$ROLES$role,"
  done

  ROLES="${ROLES%?}" # remove last coma from roles string
  if [ -z "$RESOURCES" ]; then # resource does not exist ( create new )

    # busybox shell test cmd does not work reliably, checking for ability to open file as more reliable option
    # if [ -w $WEB_XML ]; then
    if >>"$WEB_XML"; then
      $(xmlstarlet ed -L -s 'webresources/protected' \
        -t 'elem' -n 'resource' -v '' \
        -i 'webresources/protected/resource[not(@name)]' \
        -t 'attr' -n 'name' -v "$NAME" \
        -i 'webresources/protected/resource[not(@roles)]' \
        -t 'attr' -n 'roles' -v "$ROLES" "$WEB_XML")
    else
      {
        HTTP_STATUS=500
        ERROR_MESSAGE="Error adding new resource. Check '$WEB_XML' file permissions."
        return 53
      }
    fi

  else # resource exits ( update )
    [[ $(echo $POST_DATA | jq -e 'has("roles")') == "false" ]] && {
      HTTP_STATUS=400
      ERROR_MESSAGE="Parameter 'roles' is requireq for updating resource."
      return 3
    }
    # busybox shell test cmd does not work reliably, checking for ability to open file as more reliable option
    # if [ -w $WEB_XML ]; then
    if >>"$WEB_XML"; then
      $(xmlstarlet ed --inplace -u "webresources/protected/resource[@name='$NAME']/@roles" -v "$ROLES" "$WEB_XML")
    else
      {
        HTTP_STATUS=500
        ERROR_MESSAGE="Error updating resource. Check '$WEB_XML' file permissions."
        return 54
      }
    fi

  fi
  return 0
}

delete_resource() {
  if [ "$CONTENT_LENGTH" -gt 0 ]; then
    POST_DATA=$(cat -)
  fi
  NAME=$(echo $POST_DATA | jq -r '.name')
  [[ -z "$NAME" ]] && {
    HTTP_STATUS=400
    ERROR_MESSAGE="Inavalid request"
    return 4
  }
  RESOURCES=$(xmlstarlet sel -t -m "webresources/protected/resource[@name='$NAME']" -v "@name" -n "$WEB_XML")
  if [ -z "$RESOURCES" ]; then # resource does not exist can't delete
    {
      HTTP_STATUS=500
      ERROR_MESSAGE="Resource with '$NAME' name not found."
      return 55
    }
  else # delete resource
    # busybox shell test cmd does not work reliably, checking for ability to open file as more reliable option
    # if [ -w $WEB_XML ]; then
    if >>"$WEB_XML"; then
      $(xmlstarlet ed -L -d "webresources/protected/resource[@name='$NAME']" "$WEB_XML")
    else
      {
        HTTP_STATUS=500
        ERROR_MESSAGE="Error deleting resource. Check '$WEB_XML' file permissions."
        return 56
      }
    fi

  fi
  return 0
}

main() {
  WEBAUTH=$(xmlstarlet sel -t -m "application/web_resources" -v . -n /home/$APP_NAME/app.conf)
  WEB_XML="/home/$APP_NAME/$WEBAUTH"
  if [ -f $WEB_XML ]; then
    if [ "$REQUEST_METHOD" = "GET" ]; then
      get_resources
    elif [ "$REQUEST_METHOD" = "POST" ]; then
      update_resources
    elif [ "$REQUEST_METHOD" = "DELETE" ]; then
      delete_resource
    fi
    STATUS_CODE=$?
  else
    {
      HTTP_STATUS=500
      ERROR_MESSAGE="'$WEB_XML' file does not exists."
      STATUS_CODE=50
    }
  fi

  echo "Status: $HTTP_STATUS"
  echo "Content-type: application/json"
  echo ""
  if [ "$STATUS_CODE" -ne 0 ]; then
    echo "{\"errorCode\": \"$STATUS_CODE\", \"errorMessage\": \"$ERROR_MESSAGE\"}"
  else
    if [ "$REQUEST_METHOD" = "GET" ]; then
      echo "$RESOURCES_JSON"
    else
      echo "{}"
    fi
  fi
}

main
