#!/bin/bash

# Copyright: 2023 Virtuozzo International GmbH

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


inherit default fsutils extendperm envinfo;


VERSION="1";
DEFAULT_ACTION="Usage";
DESCRIPTION="Works with file system";
JFINFO="/usr/local/bin/jfinfo"
JPERM="/usr/local/bin/jperm"
function doUsage() {
    showUsageMessage;
}

FS_PATH="";
FS_USER="";
FS_SOURCE="";
FS_DESTINATION="";
FS_OVERWRITE="false";

function onModLoadCallback(){
    local temp=`getopt -o u:,s:,p:,d:,o -l user:,destinationpath:,sourcepath:,path:,overwrite -- "$@" 2>>"$JEM_CALLS_LOG"`
    [[ $? != 0 ]] && die -q "Terminating...";
    eval set -- "$temp"
    while true ; do
        case "${1}" in
            --user|-u)
                FS_USER=$2;
                shift 2;
                ;;
            --path|-p)
                FS_PATH=$2;
                shift 2;
                ;;
            -s|--sourcepath)
                FS_SOURCE=$2
                shift 2;
                ;;
            -d|--destinationpath)
                FS_DESTINATION="$2"
                shift 2;
                ;;
	    -o|--overwrite)
                FS_OVERWRITE="true"
                shift ;
                ;;

            --)
                shift;
                break;
                ;;
        esac;
    done;
    # echo "USER: ${FS_USER}|PATH: ${FS_PATH}|SOURCE: ${FS_SOURCE}|DEST: ${FS_DESTINATION}|OVER: ${FS_OVERWRITE}";
    return 0
}

# checkRights
# fileExists
# dirExists
# unitExists

function checkUser(){
    if [ -z "$FS_USER" ]; then
        writeJSONResponseErr "result=>4032" "message=>User not defined";
        return 32;
    fi
    if ! userExists "$FS_USER"; then
        writeJSONResponseErr "result=>4029" "message=>No such user $FS_USER";
        return 29;
    fi
}

function dirRead(){
    ExtendPerm ;
    local dir=${1:?"Missing param: dir"};
    if ! $( su - "$FS_USER" $JPERM $(printf '%q' "${dir}") 'r' 'x' 2>>${JEM_CALLS_LOG} ) ; then
        return 37;
    fi
    return 0;
}

function doExtendPerm(){
    $GREP -qE "^jelastic:" /etc/passwd && ExtendPerm ;
    fixModeBits;
    return 0;
}

function doList(){
    ExtendPerm ;
    checkUser ;
    local result_code=$?;
    if [ "$result_code" -gt 0 ] ; then
	return $result_code;
    fi
    if [ -z "$FS_PATH" ]; then
	writeJSONResponseErr "result=>4033" "message=>Path not defined";
	return 33;
    fi
    if ! dirExists "$FS_PATH"; then
        if ! fileExists "$FS_PATH"; then
            writeJSONResponseErr "result=>4035" "message=>Path '${FS_PATH//\"/\\\"}' not exists"
            return 35;
        else
            writeJSONResponseErr "result=>4102" "message=>'${FS_PATH//\"/\\\"}' is not directory"
            return 35;
        fi
    fi

    su - $FS_USER -c "$JFINFO $(printf '%q' "${FS_PATH}") 2>/dev/null" 2>>${JEM_CALLS_LOG} | sed -e 's/[^{]*//' -e '/^$/d';
}

# FS_PATH:
#   path - list
#   file - read

function doRead() {
    ExtendPerm ;
    checkUser ;
    local result_code=$?;
    if [ "$result_code" -gt 0 ] ; then
        return $result_code;
    fi

    if $( su - "$FS_USER" -c "${JPERM} $(printf '%q' "${FS_PATH}") 'r'" >>${JEM_CALLS_LOG} 2>&1 ) ; then
        return 0 ;
    else
	result=$?;
	if [ $result -eq 2 ] ; then
	    writeJSONResponseErr "result=>4035" "message=>Path ${FS_PATH//\"/\\\"} not exists"
	    return 35;
	else
	    writeJSONResponseErr "result=>4037" "message=>Permission denied";
	fi
        return 37;
    fi
}

function doWrite() {
	ExtendPerm ;
	checkUser ;
	local result_code=$?;
	if [ "$result_code" -gt 0 ] ; then
		return $result_code;
	fi
	if [ -z "$FS_PATH" ]; then
		writeJSONResponseErr "result=>4033" "message=>Path not defined";
		return 33;
	fi
	local parent_dir=$(dirname "$FS_PATH") ;
        if $( su - "$FS_USER" -c "${JPERM} $(printf '%q' "${FS_PATH}") 'w'" >>${JEM_CALLS_LOG} 2>&1 ) ; then
	    return 0
	else
	    result=$?
	    if [ $result -eq 2 ] ; then
		if $( su - "$FS_USER" -c "${JPERM} $(printf '%q' "${parent_dir}") 'w'" 2>>${JEM_CALLS_LOG} ) ; then
		    return 0
		else
		    if [ $result -eq 2 ] ; then
			writeJSONResponseErr "result=>4035" "message=>Path ${FS_PATH//\"/\\\"} not exists"
			return 35;
		    else
			writeJSONResponseErr "result=>4037" "message=>Permission denied";
			return 37;
		    fi
		fi
	    else
		writeJSONResponseErr "result=>4037" "message=>Permission denied";
		return 37;
	    fi
	fi
	return 0;
}

function doCreate() {
    ExtendPerm ;
    checkUser ;
    local result_code=$?;
    if [ "$result_code" -gt 0 ] ; then
        return $result_code;
    fi
    unitExists "$FS_PATH";
    unitRes=$?;
    if [ $unitRes -eq 0 -a "x${FS_OVERWRITE}" != "xtrue" ]; then

        writeJSONResponseErr "result=>4036" "message=>Path ${FS_PATH//\"/\\\"} already exists"
        return 36;
    fi
    local parent_dir=$(dirname "$FS_PATH") ;

    if $( su - "$FS_USER" -c "${JPERM} $(printf '%q' "${parent_dir}") 'w' 'x'" >>${JEM_CALLS_LOG} 2>&1 ) ; then
        return 0;
    else
	result=$?;
	if [ $result -eq 2 ] ; then
	    writeJSONResponseErr "result=>4035" "message=>Path $parent_dir not exists";
	    return 35;
	else
	    writeJSONResponseErr "result=>4037" "message=>Permission denied";
	    return 37;
	fi
    fi
    return 0;
}

function doDelete() {
    ExtendPerm ;
    checkUser ;
    local result_code=$?;
    if [ "$result_code" -gt 0 ] ; then
        return $result_code;
    fi
    if ! checkUnit "$FS_PATH"; then
        writeJSONResponseErr "result=>4035" "message=>Path ${FS_PATH//\"/\\\"} not exists"
        return 35;
    fi
    local parent_dir=$(dirname "$FS_PATH");
    if $( su - "$FS_USER" -c "${JPERM} $(printf '%q' "${parent_dir}") 'w' 'x'" >>${JEM_CALLS_LOG} 2>&1 ) ; then
        return 0;
    else
	result=$?;
	if [ $result -eq 2 ] ; then
	    writeJSONResponseErr "result=>4035" "message=>Path $parent_dir not exists";
	    return 35;
	else
	    writeJSONResponseErr "result=>4037" "message=>Permission denied";
	fi
        return 37;
    fi

    if $( su - "$FS_USER" -c "${JPERM} $(printf '%q' "${FS_PATH}") 'w'" >>${JEM_CALLS_LOG} 2>&1) ; then
        return 0;
    else
	result=$?;
	if [ $result -eq 2 ] ; then
	    writeJSONResponseErr "result=>4035" "message=>Path ${FS_PATH//\"/\\\"} not exists"
	    return 35;
	else
	    writeJSONResponseErr "result=>4037" "message=>Permission denied";
	fi
        return 37;
    fi
    return 0;
}

function doCopy() {
    ExtendPerm ;
    checkUser ;
    local result_code=$?;
    if [ "$result_code" -gt 0 ] ; then
        return $result_code;
    fi

    if ! checkUnit "$FS_SOURCE"; then
        writeJSONResponseErr "result=>4046" "message=>Source path '${FS_SOURCE//\"/\\\"}' not exists"
        return 46;
    fi
    if [ -z "$FS_DESTINATION" ]; then
        writeJSONResponseErr "result=>4033" "message=>Path not defined";
        return 33;
    fi
    FS_PATH="$FS_SOURCE";
    doRead;
    local return_result=$?;
    if [ "$return_result" -gt 0 ]; then
        return $return_result;
    fi

    if fileExists "$FS_DESTINATION"; then
        writeJSONResponseErr "result=>4047" "message=>Destination directory ${FS_DESTINATION//\"/\\\"} already exists"
        return 47;
    fi

    if [ "${FS_DESTINATION:(-1)}" == "/" ]; then
    #${FS_DESTINATION} - directory
        if ! dirExists "$FS_DESTINATION"; then
            writeJSONResponseErr "result=>4042" "message=>Destination directory ${FS_DESTINATION//\"/\\\"} not exists"
            return 42;
        else
            if ! $( su - "$FS_USER" -c "${JPERM} $(printf '%q' "${FS_DESTINATION}") 'w' 'x'" >>${JEM_CALLS_LOG} 2>&1) ; then
		writeJSONResponseErr "result=>4037" "message=>Permission denied";
		return 37;
	    fi
            local file=$(basename "$FS_SOURCE");
            if fileExists "$FS_DESTINATION/$file"; then
                writeJSONResponseErr "result=>4041" "message=>Destination file ${FS_DESTINATION//\"/\\\"}/$file already exists"
                return 41;
            fi
        fi
    else
	FS_PATH="$FS_DESTINATION";
	doWrite
        return_result=$?;
        return $return_result;
    fi
    return 0;
}

function doMove() {
    ExtendPerm ;
    doCopy ;
    local return_result=$?;
    if [ "$return_result" -gt 0 ]; then
        return $return_result;
    fi
    FS_PATH="$FS_SOURCE";
    doDelete;
    local return_result=$?;
    if [ "$return_result" -gt 0 ]; then
        return $return_result;
    fi
    return 0;
}

function doUpload() {
	doCreate
	return $?;
}

function describeRead() {
    echo "Check read permission for given file";
}

function describeCreate() {
    echo "Check possibility create a file in the specified path";
}

function describeDelete() {
    echo "Check possibility delete a file in the specified path";
}

function describeCopy() {
    echo "Check possibility copy a file from  the specified path to destination";
}

function describeMove() {
    echo "Check possibility move a file from  the specified path to destination";
}

function describeUpload() {
    echo "Check possibility upload a file to the specified path";
}

function describeReadParameters() {
    echo "-p <path> -u <user>";
}

function describeGlobalOptions(){
    echo "-p: full path";
    echo "-u: user name";
}

function describeReadOptions() {
    describeGlobalOptions
}

function describeCreateParameters() {
    echo "-p <path> -u <user>";
}

function describeCreateOptions() {
    describeGlobalOptions;
}

function describeDeleteParameters() {
    echo "-p <path> -u <user>";
}

function describeDeleteOptions() {
    describeGlobalOptions
}

function describeCopyParameters() {
    echo "-u <user> -s <source path> -d <destination path>";
}

function describeCopyOptions() {
    echo "-d: destination path";
    echo "-s: source path";
    echo "-u: user name";
}

function describeMoveParameters() {
    echo "-u <user> -s <source path> -d <destination path>";
}

function describeMoveOptions() {
    echo "-d: destination path";
    echo "-s: source path";
    echo "-u: user name";
}

function describeUploadParameters() {
    echo "-u <user> -p <path>";
}

function describeUploadOptins() {
    describeGlobalOptions
}
