#!/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.

[ -n "${EXCEPTORLIB_VERSION:-}" ] && return 0;
EXCEPTORLIB_VERSION="0.1";
DF_TIMEOUT_SEC=120

inherit fsutils;
include output;

$PROGRAM 'curl';
$PROGRAM 'gzip';
$PROGRAM 'grep';
$PROGRAM 'file';
$PROGRAM 'awk';
$PROGRAM 'unzip';
$PROGRAM 'sed';

function ensureDiskSpaceIsOK() {
    resfile=$(mktemp 2>/dev/null)
    [ -z "$resfile" ] && return 1
    timeout -s 9 $DF_TIMEOUT_SEC cat <(
        local disk_space_usage_critical_state=97
        local disk_inode_usage_critical_state=97
        if [[ -f /proc/vz/version ]]; then
            local disk_space_error=4204
            local disk_inodes_error=4205
            local additional_text=" on host"
        else
            local disk_space_error=4075
            local disk_inodes_error=4076
        fi
        local fstype="$(getFSType '/')"
        local disk_space_usage_percentage=$(df -h / 2>/dev/null  | tail -1 | $GREP -o [[:alnum:]]*% | $SED  's/%//g')
        local disk_inode_usage_percentage=$(df -i / 2>/dev/null  | tail -1 | $GREP -o [[:alnum:]]*% | $SED  's/%//g')
        [[ ${disk_space_usage_percentage} -lt ${disk_space_usage_critical_state} ]] || { writeJSONResponseErr "result=>$disk_space_error" "message=>No free diskspace$additional_text"; echo 1 > $resfile; exit; }

        [[ "${fstype}" == "reiserfs" ]] && { echo 0 > $resfile; exit; }
        [[ ${disk_inode_usage_percentage} -lt ${disk_inode_usage_critical_state} ]] || { writeJSONResponseErr "result=>$disk_inodes_error" "message=>No free inodes$additional_text"; echo 1 > $resfile; exit; }
        echo 0 > $resfile
    )
    res=$?
    [[ $res -eq 137 ]] && {
        writeJSONResponseErr "result=>4132" "message=>Execution timed out";   
        die -q;
    }
    fres=$(cat $resfile)
    /bin/rm -f $resfile
    [ -n "$fres" ] && return $fres
    return 1
}

function ensureFileCanBeUncompressed(){
    VERBOSE=1;
    local fileToUncompress="$1";
    local uncompressed_zip_size=0;
    [ -z "${resource_data_dize}" ] && { resource_data_dize=0; freebytesleft=$(( 1024 *  $(df -l / 2>/dev/null | tail -1 | $AWK '{ print $4 }' )-1024*1024)); }
    local uncompressed_size;

    mimeType=$($FILE --mime-type "${fileToUncompress}" -b)

    case ${mimeType} in
        "application/x-bzip2")
            uncompressed_size=$(( $($TAR -tvjf "$1" | $AWK '{i+=$3} END{print i}')+1048576))
        ;;
        "application/jar" | "application/zip")
            uncompressed_size=$(( $($UNZIP -Z "$1" | $GREP uncompress | $AWK '{ print $3 }' | tail -n 1 )+1048576))
        ;;
        "application/x-gzip")
            uncompressed_size=$(( $($GZIP -l "$1" | $AWK '{ print $2 }' | tail -n 1 )+1048576))
        ;;
        "application/x-tar")
            uncompressed_size=$(( $($TAR -tvf "$1" | $AWK '{i+=$3} END{print i}')+1048576))
        ;;
        *)
            log "Unknown mime-type  file ${fileToUncompress}";

    esac

    [ -z "${uncompressed_size}" ] && uncompressed_size=0;
    let "total_deploy_size = $uncompressed_size + $resource_data_dize";
    [[ ${total_deploy_size} -lt  ${freebytesleft} ]] || { clearCache; writeJSONResponseErr "result=>4075" "message=>No free diskspace"; die -q; }
    return 0;
}

function ensureFileCanBeDownloaded(){
    local resource_url=$1;
    resource_data_dize=$($CURL -s --head $resource_url | $GREP -Ei "^Content-Length" | $AWK -F ":" '{ print $2 }'| $SED 's/[^0-9]//g');
    freebytesleft=$(( 1024 *  $(df -l | $GREP "/$" | $AWK '{ print $4 }' | head -n 1)-1024*1024));
    [ -z "${resource_data_dize}" ] && return 0;
    [[ ${resource_data_dize} -lt  ${freebytesleft} ]] || { writeJSONResponseErr "result=>4075" "message=>No free diskspace"; die -q; }
    return 0;
}

function getPackageName() {
    if [ -f "$package_url" ]; then
        package_name=$(basename "${package_url}")
        package_path=$(dirname "${package_url}")
    elif [[ "${package_url}" =~ file://* ]]; then
        package_name=$(basename "${package_url:7}")
        package_path=$(dirname "${package_url:7}")
        [ -f "${package_path}/${package_name}" ] || { writeJSONResponseErr "result=>4078" "message=>Error loading file from URL"; die -q; }
    else
	createDownloadsDir;
        ensureFileCanBeDownloaded $package_url;
        $WGET --no-check-certificate --content-disposition --directory-prefix="$DOWNLOADS" $package_url >> $ACTIONS_LOG 2>&1 || { writeJSONResponseErr "result=>4078" "message=>Error loading file from URL"; die -q; }
        sed -i '/ \.\......... ........./d' $ACTIONS_LOG
        package_name="$(ls ${DOWNLOADS})";
        [[ "${package_name}" != "$(ls ${DOWNLOADS} | awk -F? '{print $1}')" ]] && { mv ${DOWNLOADS}/${package_name} ${DOWNLOADS}/$(ls ${DOWNLOADS} | awk -F? '{print $1}'); package_name="$(ls ${DOWNLOADS})"; }
        package_path=${DOWNLOADS};
        [ ! -s "${package_path}/${package_name}" ] && {
            set -f
            rm -f "${package_name}";
            set +f
            writeJSONResponseErr "result=>4078" "message=>Error loading file from URL";
            die -q;
        }
    fi
}

function createDownloadsDir() {
    [ ! -d "$DOWNLOADS" ] && ${SUDO_COMMAND} /usr/bin/mkdir -p ${DOWNLOADS}
    ${SUDO_COMMAND} /usr/bin/setfacl -Rm g:ssh-access:xwr,d:g:ssh-access:xwr,d:u::xwr ${DOWNLOADS}
}


function clearCache(){
    if [[ -d "$DOWNLOADS" ]]
    then
       shopt -s dotglob;
       set -f
       rm -Rf ${DOWNLOADS}/*;
       set +f
       shopt -u dotglob;
    fi
}

