#!/bin/bash

# if [ ${git_helpers_sourced:-1} = "1" ]; then
#    readonly git_helpers_sourced=${BASH_SOURCE[0]}
#else
#    return 0
#fi

source ./general_utils

exec_opkg_command () {
    local func="${FUNCNAME[0]}"
    log_debug "$func:${LINENO} exec-ing [$*]"

    local __result=$(exec_process_substitution $*)
    local __result_code=$?

    log_debug "$func:${LINENO} result=$__result"

    printf '%s' "$__result"
    return $__result_code
}

# Fetch/merge updates from predefined repository using git.
# 
fetch_customer_updates() {
    local func="${FUNCNAME[0]}"
    if ! pull_customer_repository $1; then
        return 1
    fi
    return 0
}

copy () {
    local func="${FUNCNAME[0]}"

    readarray -td' ' files <<< "$1"
    for f in ${files[@]}; do
        if grep -qE "^.*[.]conf.*$" <<< ${f}; then
            local __f="${psa_config_dir}/${f}"
            if ! cp ${__f} /etc/psa_config; then
                log_error "$func:${LINENO}: cannot cp ${__f} /etc/psa_config"
                return 1
            fi
            log_info "$func:${LINENO}: copied $f to /etc/psa_config"
        # elif grep -qE "^.*[.]ini.*$" <<< ${f}; then
        #    if ! cp ${f} $psa_ini; then
        #        return 1
        #    fi
        fi
    done

    log_debug "$func:${LINENO}: copied *conf/*ini-files to system-dirs"
    return 0;
}
    
filter_system_files () {
    local func="${FUNCNAME[0]}"

    readarray -td' ' files <<< "$1"
    local __system_files=""
    for f in ${files[@]}; do
        case "$f" in
            ("emp.conf"|"printer.conf"|"device.conf")
                __system_files+="${f} "
                ;;
        esac    
    done

    log_debug "$func:${LINENO} system-files=$__system_files"
    printf '%s' "$__system_files"
}


# Check if the fetched/merged files have the correct md5 and are
# valid for the PSA.
#
check_md5_for_changed_conf_and_ini_files () {
    local func="${FUNCNAME[0]}"
    local json_key=""
    local md5sum_update_conf=""
    local md5sum_repository=""
    log_debug "$func:${LINENO} files=$1"
    if ! [ -z $1 ]; then
        readarray -td' ' files <<< "$1"
        for file in ${files[@]}; do
            if [ "$file" = "emp.conf" ]; then
                json_key=".conf.szeged.zg1.z1.etc.psa_config.emp"
                md5sum_update_conf=$(cat $update_conf | jq -r $json_key)
                md5sum_repository="$(md5sum $emp_conf | awk '{ print $1}')"
            elif [ "$file" = "printer.conf" ]; then
                json_key=".conf.szeged.zg1.z1.etc.psa_config.printer"
                md5sum_update_conf=$(cat $update_conf | jq -r $json_key)
                md5sum_repository="$(md5sum $printer_conf | awk '{ print $1}')"
            elif [ "$file" = "device.conf" ]; then
                json_key=".conf.szeged.zg1.z1.etc.psa_config.device"
                md5sum_update_conf=$(cat $update_conf | jq -r $json_key)
                md5sum_repository="$(md5sum $device_conf | awk '{ print $1}')"
            else
                continue
            fi

            if [ "$md5sum_repository" = "$md5sum_update_conf" ]; then
                log_info "$func:${LINENO}: md5sum for $file ok"
            else
                local __r="repository: $md5sum_repository"
                local __u="update.conf=$md5sum_update_conf"
                local __m="$__r != $__u"
                log_error "$func:${LINENO}: md5sum for $file wrong: $__m"
                return 1
            fi
        done
    else
        log_debug "$func:${LINENO} no changed conf-/ini-files"
    fi
    return 0
}

check_md5_for_opkg_packages () {
    local func="${FUNCNAME[0]}"
    local -n opkg_output_ref=$1
    local package=""
    local md5sum_opkg_info=""
    local filename=""
    for line in ${opkg_output_ref[@]}; do
        log_info "$func:${LINENO}: line=$line"
        if grep -qE "^\s*Package\s*:.*?$" <<< "$line"; then
            package=${line#*:* }
        elif grep -qE "^\s*MD5Sum\s*:.*?$" <<< "$line"; then
            md5sum_opkg_info=${line#*:* }
        elif grep -qE "^\s*Filename\s*:.*?$" <<< "$line"; then
            filename=${line#*:* }
        fi
    done

    local __update_conf="${customer_location_dir}/update.conf"
    md5sum_repo=$(cat $__update_conf | jq -r .opkg.${package}.MD5Sum)
    if ! [ -z $md5sum_repo ]; then
        if [ "$md5sum_opkg_info" = "$md5sum_repo" ]; then
            log_info "$func:${LINENO}: md5 $md5sum_repo OK for $package"
            return 0
        else
            log_error "$func:${LINENO}: md5sum_repo [$md5sum_repo] "\
                "!= md5sum_opkg_info [$md5sum_opkg_info] for $package"
        fi
    else
        log_error "$func:${LINENO}: md5sum_repo empty"
    fi

    return 1
}

# In case the new checked-out files are not correct, revert the git
# repository to its previous state.
#
revert_customer_repository () {
    local func="${FUNCNAME[0]}"
    return 0
}

# Backup before the update-process. 
#
backup_previous_version () {
    local func="${FUNCNAME[0]}"
    return 0
}

exec_opkg_info () {
    local func="${FUNCNAME[0]}"
    log_info "$func:${LINENO}: executing info $1"
    
    opkg_result=$(exec_opkg_command "opkg info $1")
    if [ $? -eq 0 ]; then
        # make sure the keywords start with '\n'
        opkg_result=$(sed -E -e "s/(^.*)(Package)(.*$)/\n\2\3/g"\
                -e "s/(^.*)(Version)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*)(Depends)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*)(Status)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*)(Architecture)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*)(Maintainer)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*)(MD5Sum)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*)(Filename)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*)(Source)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*)(Description)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*)(Installed-Size)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*)(Section)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*[^-])(Size)(.*$)/\1\n\2\3/g"\
                -e "s/(^.*)(Installed-Time)(.*$)/\1\n\2\3/g"
                    <<< "$opkg_result")

        local -n output_ref=$2

        readarray -d $'\n' output_ref < <(printf '%s' "$opkg_result")
        if [ $? -ne 0 ]; then
            log_error "$func:${LINENO}: readarray finished with error"
            return 1
        fi
    
        log_info "$func:${LINENO}: ... done"
        # log_info "$func:${LINENO}: opkg_result=${output_ref[@]}"
        return 0
    fi

    log_error "$func:${LINENO}: executing info $1"
    return 1
}

# Try to install new opkg-packages (in case the are some
# in the new git-checkout).
#
exec_opkg_noaction() {
    local func="${FUNCNAME[0]}"
    local opkg_command_no_action="opkg --noaction $1"
    log_debug "$func:${LINENO}: executing $opkg_command_no_action"
    
    local __opkg_result=$(exec_opkg_command "opkg --noaction $1")
    if [ $? -eq 0 ]; then
        log_info "$func:${LINENO}: opkg_result=$__opkg_result"
        return 0
    fi

    log_error "$func:${LINENO}: error executing opkg --noaction $1"
    return 1
}

# Install the new packages using opkg. 
#
exec_opkg () {
    local func="${FUNCNAME[0]}"
    log_debug "$func:${LINENO}: executing $1"
    
    local __opkg_result=$(exec_opkg_command "opkg $1")
    if [ $? -eq 0 ]; then
        log_info "$func:${LINENO}: opkg_result=$__opkg_result"
        return 0
    fi

    log_error "$func:${LINENO}: error executing $1"
    return 1
}

# In case there was some error, re-install the previous package(s)
# and use the backup to restore any conf/ini-files.
#
fallback_to_previous_version() {
    local func="${FUNCNAME[0]}"
    return 0;
}

# If all went well, then execute all necessary cleanup steps.
#
cleanup_previous_version() {
    local func="${FUNCNAME[0]}"
    return 0
}