#! /bin/bash
#------------------------------------------------------------------------------
#$Author: andrius $
#$Date: 2019-09-18 09:44:32 -0400 (Wed, 18 Sep 2019) $
#$Revision: 4689 $
#$URL: svn://saulius-grazulis.lt/restful/tags/v0.16.0/tools/scripts/restfuldb-client $
#------------------------------------------------------------------------------
#*
#  Client of the RESTfulDB API.
#
#  USAGE:
#    $0 --config curl-config.cf --url https://localhost/restful/website/db/table/1 --get
#**

CURL=curl
JSON_PP="json_pp -json_opt canonical,indent"

CURL_CONFIG=
CACERT=
CERT=

BASE_URL=
TYPE=
RECORD_ID=

URL=

JSONFILE=

ACTION=get

die () {
    echo $0: $1 >&2
    exit 255
}

#** OPTIONS:
#**  --base-url, --base
#**     Base URL of a database's RESTfulDB API.
#**
#**  --table, --type, -t
#**     Table name.
#**
#**  --id, --record-id
#**     ID of a record to retrieve or modify (optional).
#**
#**  --url
#**     Complete URL for the request, containing the name of a table and
#**     record ID, if needed.
#**
#**  --get
#**     Retrieve record(s) (default action).
#**
#**  --add, --create, --insert, --put
#**     Create a record with given attributes.
#**
#**  --change, --update, --patch
#**     Modify a record.
#**
#**  --delete, --remove
#**     Delete a record.
#**
#**  --cacert
#**     TLS certificate to verify the server.
#**
#**  --cert
#**     Certificate to identify the client.
#**
#**  --config
#**     Configuration file for curl.
#**
#**  --json-pp 'son_pp -json_opt canonical,indent'
#**     Specify a command to postprocess the retrieved JSON data.
#**
#**  --no-run
#**     Print the curl command instead of executing it.
#**
#**  --verbose
#**     Turn on verbose mode for curl.
#**
#**  --help
#**     Print short help message (this message) and exit
while [ $# -gt 0 ]
do
  case $1 in
    --url)
        URL="$2"
        shift
        ;;
    --base-url|--base)
        BASE_URL="$2"
        shift
        ;;
    --table|--type|-t)
        TYPE="$2"
        shift
        ;;
    --record-id|--record|--id)
        RECORD_ID="$2"
        shift
        ;;
    --get)
        ACTION=get
        ;;
    --add|--create|--insert|--put)
        ACTION=put
        ;;
    --change|--update|--patch)
        ACTION=patch
        ;;
    --delete|--remove)
        ACTION=delete
        ;;
    --cacert)
        CACERT="$2"
        shift
        ;;
    --cert)
        CERT="$2"
        shift
        ;;
    --config|--conf)
        CURL_CONFIG="$2"
        shift
        ;;
    --json-pp)
        JSON_PP="$2"
        shift
        ;;
    --no-run)
        CURL='echo curl'
        ;;
    --verbose)
        CURL='curl -v'
        ;;
    --help|--hel|--he|--h)
        awk '/#\*/,/#\*\*/ {
                sub("^ *#[*]?[*]?", ""); \
                gsub("\\$0","'$0'"); \
                print $0
            }' $0
        exit
        ;;
    --options|--option)
        die "'--options' is a placeholder; please use '$0 --help' to get the list of available options."
        ;;
    -*)
        die "unknown option: $1"
        ;;
    *)
        test -n "${JSONFILE}" && die "only one file can be supplied"
        JSONFILE="$1"
        ;;
  esac
  shift
done

case ${ACTION} in
  delete)
    REQUEST=DELETE
    test -n "${JSONFILE}" && die "DELETE request does not need an input"
    ;;
  get)
    test -n "${JSONFILE}" && die "GET request does not need an input"
    ;;
  patch)
    REQUEST=PATCH
    ;;
  put)
    REQUEST=PUT
    ;;
esac

test -z "${JSONFILE}" && JSONFILE=-

if [ -z "${URL}" ]
then
    test -z "${BASE_URL}" && die "either full URL or base URL must be given"
    test -z "${TYPE}" && die "either full URL or entry type must be given"

    URL="${BASE_URL}/${TYPE}"
    test -n "${RECORD_ID}" && URL="${URL}/${RECORD_ID}"
fi

case ${ACTION} in
  delete|get)
    ${CURL} -sSL \
        $(test -n "${CURL_CONFIG}" && echo --config ${CURL_CONFIG}) \
        $(test -n "${CACERT}" && echo --cacert ${CACERT}) \
        $(test -n "${CERT}" && echo --cert ${CERT}) \
        $(test -n "${REQUEST}" && echo --request ${REQUEST}) \
        --header 'Accept: application/json' \
        --output - \
        "${URL}" \
        | ${JSON_PP}
    ;;
  *)
    ${CURL} -sSL \
        $(test -n "${CURL_CONFIG}" && echo --config ${CURL_CONFIG}) \
        $(test -n "${CACERT}" && echo --cacert ${CACERT}) \
        $(test -n "${CERT}" && echo --cert ${CERT}) \
        $(test -n "${REQUEST}" && echo --request ${REQUEST}) \
        --header 'Accept: application/json' \
        --header 'Content-Type: application/json' \
        --data-binary @${JSONFILE} \
        --output - \
        "${URL}" \
        | ${JSON_PP}
    ;;
esac
