#! /bin/zsh

TMP=${TMP:-/tmp}

verbose=""

showHelp=""
showVersion=""

toolchain="r-lang-xml"
mode="xml"

OPX_SERVER_DEF="https://johannes-willkomm.de/opx"
OPX_SERVER="${OPX_SERVER:-${OPX_SERVER_DEF}}"

server="$OPX_SERVER/transform/"

optionsfile=${OPX_CLIENT_OPTIONS:-~/.opx/client-options}

typeset -A transformFlags

optstring=":DhVvFfH:rs:S:m:o:p:x:-:"
option=""

method="method-tcproc"

output="-"

result=0

while getopts "$optstring" option; do
    case $option in
        (\?)
        echo "opx-client: error: illegal option -$OPTARG specified" >&2
        exit 1
        ;;
        (\:)
        echo "opx-client: error: argument expected after -$OPTARG option" >&2
        exit 1
        ;;
        ("-")
        case $OPTARG in
            (help)
            showHelp="yes"
            ;;
            (version)
            showVersion="yes"
            ;;
            (tmp-dir)
            userTmpDir=$argv[OPTIND]
            let OPTIND=OPTIND+1
            ;;
            (server)
            server=$argv[OPTIND]
            let OPTIND=OPTIND+1
            ;;
        esac
        ;;
        (D)
        set -x
        debug=1
        ;;
        (V)
        verbose=1
        ;;
        (h)
        showHelp="yes"
        ;;
        (H)
        header=$OPTARG
        ;;
        (v)
        method="method-version"
        ;;
        (o)
        output="$OPTARG"
        ;;
        (m)
        toolchain="$OPTARG"
        ;;
        (x)
        mode="$OPTARG"
        ;;
        (p)
        optionsfile="$OPTARG"
        ;;
        (s)
        arg=$OPTARG
        pname="${arg/%\=*/}"
        pvalue="${arg/$pname=/}"
#        echo "transform param: '$pname'='$pvalue'"
        if [[ -z "$pvalue" ]]; then
            transformFlags[$pname]=1
        else
            transformFlags[$pname]=$pvalue
        fi
        ;;
        (S)
        server=$OPTARG
        ;;
    esac
done
        
infile="$argv[$OPTIND]"

if [[ -n "$showVersion" ]]; then
    rev='$Revision$'
    echo "opx-client $rev[12,-3]"
    exit
fi

if [[ -n "$showHelp" ]]; then
    echo " "
    echo "    .*.*.  opx-client: Send data to OPX server ($server) .*.*. " 
    echo " "
    echo " usage: opx-client [options] file"
    echo " "

    echo " Options:"
    echo " -h     | --help            - show help and exit"
    echo "        | --version         - show help and exit"
    echo " -D                         - debug this script"
    echo " -m name                    - transformation mode"
    echo " -x mode                    - output mode: xml or soap"
    echo " -s name=value              - set parameter"
    echo " -S URL                     - server URL (default: \$OPX_SERVER)"
    echo " -p file                    - options file"
    exit
fi

if [[ -z "$userTmpDir" ]]; then
    mypid=$$
    tmpBase="$TMP/opx"
    tmpdir=$tmpBase/opx-$mypid
    rm -rf $tmpdir
    if ! [[ -d "$tmpBase" ]]; then
        mkdir $tmpBase
        chmod a+rwx $tmpBase
    fi
    mkdir $tmpdir
    chmod og-rwx $tmpdir
else
    tmpdir=$userTmpDir
fi
if ! [[ -w $tmpdir ]]; then
    echo "opx-client: error: the temporary directory $tmpdir is not writable" >&2
    exit 1
fi

if [[ "$infile" = "-" ]]; then
    infile=$tmpdir/input.dat
    cat - > $infile
else
    if [[ -z "$infile" ]]; then
        echo "error: no input file"
        exit 1
    elif ! [[ -e "$infile" ]]; then
        echo "error: input file '$infile' does not exist"
        exit 1
    fi
    if ! [[ -r "$infile" ]]; then
        echo "error: input file '$infile' is not readable"
        exit 1
    fi
fi

outfile=$tmpdir/output-data
if [[ "$output" = "-" ]]; then
else
    if [[ -e "$output" ]] && ! [[ -w "$output" ]]; then
        echo "opx-client: error: the output file '$output' is not writable" >&2
        exit 1
    fi
fi


n=0
moreopts=()
for k in ${(k)transformFlags}; do
    pname=$k
    pvalue=${transformFlags[$k]}
    moreopts=($moreopts -F pname$n=$pname)
    moreopts=($moreopts -F pvalue$n=$pvalue)
    n=$(( $n + 1 ))
done

if [[ "$debug" = "1" ]]; then
    moreopts=($moreopts --verbose)
fi

legalDocsAccept=
OPT_LINE=
if [[ -f "$optionsfile" ]]; then
    exec {fd}< $optionsfile
    while read -u $fd OPT_LINE; do
        if [[ -z "${OPT_LINE}" ]]; then
            continue
        fi
        if [[ "${OPT_LINE:0:1}" = "#" ]]; then
            continue
        fi
        moreopts=($moreopts -F "$OPT_LINE")
        if [[ "$OPT_LINE" = "accept-terms-of-use-and-privacy-stmt=yes" ]]; then
            legalDocsAccept=1
        fi
    done
    exec {fd}<&-
fi
#if [[ -n "$OPX_CLIENT_ACCEPT_LEGAL_DOCS" ]]; then
#    moreopts=($moreopts -F "accept-terms-of-use-and-privacy-stmt=$OPX_CLIENT_ACCEPT_LEGAL_DOCS")
#    if [[ "$OPX_CLIENT_ACCEPT_LEGAL_DOCS" = "yes" ]]; then
#        legalDocsAccept=1
#    fi
#fi

if [[ "$legalDocsAccept" != "1" ]]; then
    echo ""
    echo "--------------------------------------------------------------------------------"
    echo ""
    echo "Please accept the OPX Terms of Use and the Privacy Statement,"
    echo "before using the OPX server."
    echo ""
    echo " - See ${OPX_SERVER}terms.html for the Terms of Use"
    echo " - See ${OPX_SERVER}privacy.html for the Privacy Statement"
    echo ""
    echo "Please create a file $optionsfile with the following line"
    echo ""
    echo " accept-terms-of-use-and-privacy-stmt=yes"
    echo ""
    echo "if you agree to both the Terms of Use and the Privacy Statement"
    echo ""
    echo "--------------------------------------------------------------------------------"
    echo ""
    exit 0
fi

curlopts=()
if [[ -n "$header" ]]; then
    curlopts=($curlopts "-D" $tmpdir/headers.txt)
fi

if [[ $verbose -gt 0 ]]; then
    echo "Contact OPX server $server"
fi

curl -s -q -F "fname1=$(basename $infile)" -F "mode=$toolchain" -F "output=$mode" -F "$method=" ${moreopts[@]} \
    -F "data1=@$infile" $curlopts $server > $outfile

if [[ -n "$header" ]]; then
    if [[ "$header" = "-" ]]; then
        cat $tmpdir/headers.txt
    else
        cp $tmpdir/headers.txt $header
    fi
fi

if [[ "$output" = "-" ]]; then
    cat $outfile
else
    cp $outfile $output
fi

function cleanUp(); {
    if [[ -z "$userTmpDir" ]]; then
        rm -rf $tmpdir
        res=$?
        if [[ "$res" != "0" ]]; then
            echo "failed to remove temporary directory $tmpdir ..." >& 2
            exit $res
        fi
    fi
}

cleanUp
