#####
##### This file is part of Mail-in-a-Box-LDAP which is released under the
##### terms of the GNU Affero General Public License as published by the
##### Free Software Foundation, either version 3 of the License, or (at
##### your option) any later version. See file LICENSE or go to
##### https://github.com/downtownallday/mailinabox-ldap for full license
##### details.
#####

#
# requires:
#    system packages: [ curl ]
#    scripts: [ color-output.sh, misc.sh, locations.sh, carddav.sh ]
#

webdav_url() {
    local user="$1"
    local path="${2:-/}"
    # nextcloud_url is defined in carddav.sh
    local nc_url="$(nextcloud_url)"
    echo "${nc_url%/}/remote.php/dav/files/$user${path%/}"
}

webdav_rest() {
    # issue a WebDAV rest call to Nextcloud
    #
    # eg: webdav_rest PROPFIND / qa@abc.com Test_1234
    #
    # The function will set the following global variables regardless
    # of exit code:
    #     REST_HTTP_CODE
    #     REST_OUTPUT
    #     REST_ERROR
    #     REST_ERROR_BRIEF
    # 
    # Return values:
    #   0 indicates success (curl returned 0 or a code deemed to be
    #     successful and HTTP status is >=200  but <300)
    #   1 curl returned with non-zero code that indicates and error
    #   2 the response status was <200 or >= 300
    #
    # Debug messages are sent to stderr
    #   
    local verb="$1"
    local uri="$2"
    local auth_user="$3"
    local auth_pass="$4"
	shift; shift; shift; shift  # remaining arguments are data

    local url
    case "$uri" in
        http* )
            url="$uri"
            ;;
        * )
            url="$(webdav_url "$auth_user")${uri#/}"
            ;;
    esac
    
    local data=()
	local item output onlydata="false"
	
	for item; do
        case "$item" in
            -- )
                onlydata="true"
                ;;
            --* )
                # curl argument
                if $onlydata; then
                    data+=("--data" "$item");
                else
                    data+=("$item")
                fi
                ;;
            * )
                onlydata="true"
                data+=("--data" "$item");
                ;;
        esac
    done
    
    local ct='text/xml; charset="utf-8"'
    local tmp1="/tmp/curl.$$.tmp"
    
    echo "spawn: curl -w \"%{http_code}\" -X $verb -H 'Content-Type: $ct' --user \"${auth_user}:xxx\" ${data[@]} \"$url\"" 1>&2
	output=$(curl -s -S -w "%{http_code}" -X $verb -H "Content-Type: $ct" --user "${auth_user}:${auth_pass}" "${data[@]}" "$url" 2>$tmp1)
	local code=$?

	# http status is last 3 characters of output, extract it
	REST_HTTP_CODE=$(awk '{S=substr($0,length($0)-2)} END {print S}' <<<"$output")
	REST_OUTPUT=$(awk 'BEGIN{L=""}{ if(L!="") print L; L=$0 } END { print substr(L,1,length(L)-3) }' <<<"$output")
	REST_ERROR=""
    REST_ERROR_BRIEF=""
	[ -z "$REST_HTTP_CODE" ] && REST_HTTP_CODE="000"

    if [ $code -ne 0 -o \
               $REST_HTTP_CODE -lt 200 -o \
               $REST_HTTP_CODE -ge 300 ]
    then
        if [ $code -ne 0 -a "$REST_HTTP_CODE" == "000" ]; then
            REST_ERROR="exit code $code"
            REST_ERROR_BRIEF="$REST_ERROR"
        else
		    REST_ERROR="REST status $REST_HTTP_CODE: $REST_OUTPUT"
            REST_ERROR_BRIEF=$(python3 -c "import xml.etree.ElementTree as ET; print(ET.fromstring(r'''$REST_OUTPUT''').find('s:message',{'s':'http://sabredav.org/ns'}).text)" 2>/dev/null)
            if [ -z "$REST_ERROR_BRIEF" ]; then
                REST_ERROR_BRIEF="$REST_ERROR"
            else
                REST_ERROR_BRIEF="$REST_HTTP_CODE: $REST_ERROR_BRIEF"
            fi
            if [ $code -ne 0 ]; then
                REST_ERROR_BRIEF="exit code $code: $REST_ERROR_BRIEF"
                REST_ERROR="exit code $code: $REST_ERROR"
            fi
        fi

        if [ -s $tmp1 ]; then
            REST_ERROR="$REST_ERROR: $(cat $tmp1)"
            REST_ERROR_BRIEF="$REST_ERROR_BRIEF: $(cat $tmp1)"
        fi
        rm -f $tmp1
        
		echo "${F_DANGER}$REST_ERROR${F_RESET}" 1>&2
		[ $code -ne 0 ] && return 1
        return 2
	fi
    
	echo "CURL succeded, HTTP status $REST_HTTP_CODE" 1>&2
	echo "$output" 1>&2
    rm -f $tmp1
	return 0    
}