#!/bin/bash

update_system_and_install_jq() {
    os=$(uname -s)

    case "$os" in
        Linux*)
            echo "Detected Linux OS."
            if [ -x "$(command -v apt-get)" ]; then
                # Update Ubuntu and Debian package lists
                apt-get update -y
                apt-get install jq -y

                if [ -f /etc/lsb-release ] && grep -q 'Ubuntu' /etc/lsb-release; then
                    wget https://download.cloudclusters.io/install_header.sh
                    bash install_header.sh
                    rm -f install_header.sh
                fi
            elif [ -x "$(command -v yum)" ]; then
                # Update CentOS package lists
                if [ "$(hostnamectl|grep Operating|awk '{print $5}')" == "8" ];then
                    wget -O - https://download.cloudclusters.io/yumrepo.sh|bash
                fi
                yum update -y
                yum install jq -y
                if [ -d /etc/ssh/sshd_config.d/ ]; then
                    rm -rf /etc/ssh/sshd_config.d/*
                fi
                sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
                sed -i 's/PermitRootLogin no/PermitRootLogin yes/g' /etc/ssh/sshd_config
                sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
                service sshd restart
                setenforce 0
            elif [ -x "$(command -v dnf)" ]; then
                # Update Fedora package lists
                dnf check-update -y
                dnf install jq -y
                sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
                setenforce 0
                sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
                service sshd restart
            elif [ -x "$(command -v zypper)" ]; then
                # Update openSUSE package lists
                zypper refresh 
                zypper install jq 
            elif [ -x "$(command -v pacman)" ]; then
                # Update Arch Linux package lists
                pacman -Sy
                pacman -S jq --noconfirm
            elif [ -x "$(command -v apk)" ]; then
                # Update Alpine package lists
                apk update
                apk add jq
            else
                echo "Unsupported package manager"
                exit 1
            fi
            ;;
        *)
            echo "Unsupported operating system: $os"
            exit 1
            ;;
    esac
}

update_system_and_install_jq

download_path="https://download.cloudclusters.io/appinstall/linux/"
params=$(echo $1 |base64 -d)
os=$(echo "$params" | jq -r '.os')
format_disk=$(echo "$params" | jq -r '.format_disk')
task_uuid=$(echo "$params" | jq -r '.task_uuid')
#download_path=$(echo "$params" | jq -r '.download_path')
auth_base64=$(echo "$params" | jq -r '.task_info')
callbackurl=$(echo "$params" | jq -r '.callbackurl')
appinfo=$(echo "$params" | jq -r '.info')

retry_post_request() {
    local url=$1
    local data=$2
    local auth=$3
    local retries=3
    local response_code

    for ((i=1; i<=$retries; i++)); do
        echo "Attempt $i"
        response_code=$(curl -s -o /dev/null -w "%{http_code}" -X POST -H "Authorization: Basic $auth" -H "Content-Type: application/json" -d "$data" $url)

        if [ $response_code -eq 200 ]; then
            echo "Request successful (HTTP $response_code)"
            break
        else
            echo "Request failed (HTTP $response_code)"
            if [ $i -eq $retries ]; then
                echo "Max retries reached, exiting..."
            else
                echo "Retrying in 10 seconds..."
                sleep 10
            fi
        fi
    done
}

index=1
process_flag="Progressing"
process_json_string="[]"
json_array=()
all_success=true

apps_toinstall=$(echo $appinfo|jq '[.[] |.verbose_name]')

# Format disk
if [[ "$format_disk" == [Tt][Rr][Uu][Ee] ]]; then
    echo "Formatting disk..."
    formatdiskscriptpath="${download_path}/${os}/formatdisk.sh"
    formatdiskscript=$(echo $formatdiskscriptpath | tr '[:upper:]' '[:lower:]')
    wget $formatdiskscript -O formatdisk.sh
    chmod +x formatdisk.sh
    ./formatdisk.sh $format_disk

    if [ $? -eq 0 ]; then
        status="Success"
        process_flag="Progressing"
        desc="The disk has been formatted successfully."
    else
        diskformatfailed="true"
        status="Failure"
        process_flag="Progressing"
        desc="The disk formatting failed or mount error."
    fi
    process_info="{\"status\": \"$status\", \"description\": \"$desc\", \"pending_apps\": $apps_toinstall}"
    process_json_array+=("$process_info")
    process_json_string=$(printf "%s\n" "${process_json_array[@]}" | jq -s '.')
    response_body="{\"task_uuid\": \"$task_uuid\", \"final_status\": \"$process_flag\", \"process_info\": $process_json_string}"
    echo $response_body
    retry_post_request "$callbackurl" "$response_body" "$auth_base64"

    rm -rf formatdisk.sh
fi

installed_apps='[]'
for row in $(echo "$appinfo" | jq -r '.[] | @base64'); do
    _jq() {
     echo ${row} | base64 --decode | jq -r ${1}
    }

    appname=$(_jq '.appname')
    version=$(_jq '.version')
    params=$(_jq '.params')
    verbose_name=$(_jq '.verbose_name')
    if [[ $params == "null" ]]; then
      params=""
    fi

    echo "Install App$index："
    echo "App Name：$appname"
    echo "App Version：$version"
    echo "App Verbose_name：$verbose_name"
    echo "App Params：$params"

    #installed_apps=$(echo "$installed_apps" | jq --arg item "$verbose_name" '. + [$item]')
    #remaining_apps=$(jq -n --argjson all "$apps_toinstall" --argjson installed "$installed_apps"  '$all - $installed')

    # Install App
    scriptname="$os-$appname-$version.sh"
    installscript=$(echo $scriptname | tr '[:upper:]' '[:lower:]')
    downloadurlpath="${download_path}/${os}/${appname}/${installscript}"
    downloadurl=$(echo $downloadurlpath |tr '[:upper:]' '[:lower:]')
    wget $downloadurl -O $installscript

    if [ $? -eq 0 ]; then
      chmod +x $installscript
      exec_res=`./$installscript $params`
      if [ $? -eq 0 ]; then
          status="Success"
          process_flag="Progressing"
          desc="Task $task_uuid running install $appname Completed. $exec_res"
    	  installed_apps=$(echo "$installed_apps" | jq --arg item "$verbose_name" '. + [$item]')
      else
          status="Failure"
          process_flag="Failure"
          desc="Task $task_uuid running install $appname has Exception. $exec_res"
      fi
    else
      status="Failure"
      process_flag="Failure"
      all_success=false
      desc="Task $task_uuid running install $appname has Exception. Download $installscript failed."
    fi

    remaining_apps=$(jq -n --argjson all "$apps_toinstall" --argjson installed "$installed_apps"  '$all - $installed')
    process_info="{\"status\": \"$status\", \"description\": \"$desc\", \"pending_apps\": $remaining_apps}"
    process_json_array+=("$process_info")
    process_json_string=$(printf "%s\n" "${process_json_array[@]}" | jq -s '.')
    response_body="{\"task_uuid\": \"$task_uuid\", \"final_status\": \"$process_flag\", \"process_info\": $process_json_string}"

    # Send Message
    echo $response_body
    retry_post_request "$callbackurl" "$response_body" "$auth_base64"

    ((index++))

    if [ "$status" = "Failure" ]; then
        exit 1
    fi

done

sleep 10

process_flag="Success"

if [ "$diskformatfailed" = "true" ]; then
    process_flag="Failure"
fi

response_body="{\"task_uuid\": \"$task_uuid\", \"final_status\": \"$process_flag\", \"process_info\": $process_json_string}"
echo $response_body
retry_post_request "$callbackurl" "$response_body" "$auth_base64"


# Clean scripts
for row in $(echo "$appinfo" | jq -r '.[] | @base64'); do
    _jq() {
     echo ${row} | base64 --decode | jq -r ${1}
    }
    appname=$(_jq '.appname')
    version=$(_jq '.version')

    # remove scripts
    removescriptname="$os-$appname-$version.sh"
    removeinstallscript=$(echo $removescriptname | tr '[:upper:]' '[:lower:]')
    echo "Remove $removeinstallscript"
    rm -rf $removeinstallscript
done

# curl -k https://gitlab.cloudclusters.net/applications/diskmonitor-deploy/-/raw/main/deploy-diskmonitor-linux.sh | bash

rm -rf deployapp.sh


