#!/bin/bash

## Copyright (C) 2012 - 2025 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

set -e
set -o pipefail

scriptname="$(basename -- "${BASH_SOURCE[0]}")"

error_handler() {
   local exit_code="$?"

   local msg="\
###############################################################################
## $scriptname script bug.
## No panic. Nothing is broken. Just some rare condition has been hit.
## Try again later. There is likely a solution for this problem.
## Please see Whonix News, Whonix Blog and Whonix User Help Forum.
## Please report this bug!
##
## BASH_COMMAND: $BASH_COMMAND
## exit_code: $exit_code
###############################################################################\
"
   echo "$msg" >&2
   if [ ! -d ~/".msgcollector" ]; then
      mkdir --parents ~/".msgcollector"
   fi
   echo "$scriptname: BASH_COMMAND: $BASH_COMMAND | exit_code: $exit_code" | tee -a ~/".msgcollector/msgdispatcher-error.log" >/dev/null
   exit 1
}

trap "error_handler" ERR

parse_cmd_options() {
   trap "error_handler" ERR

   ## Thanks to:
   ## http://mywiki.wooledge.org/BashFAQ/035

   while true; do
       case $1 in
           --verbose)
               set -x
               verbose="1"
               shift
               ;;
           --identifier)
               identifier="$2"
               shift 2
               ;;
           --progress)
               progress="$2"
               shift 2
               ;;
           --progressbaridx)
               progressbaridx="$2"
               shift 2
               ;;
           --)
               shift
               break
               ;;
           -*)
               echo "$scriptname unknown option: $1" >&2
               exit 1
               ;;
           *)
               break
               ;;
       esac
   done

   ## If there are input files (for example) that follow the options, they
   ## will remain in the "$@" positional parameters.
}

safe_file_write() {
  ## For extra security against freezing while trying to write to a non-existing pipe, let's use timeout.
  ## Use printf with positional arg to avoid shell injection.
  timeout 1 /bin/bash -c 'printf "%s\n" "$1"' -- "$1" > "$2"
}

progress_bar() {
   trap "error_handler" ERR

   ## provided by: /usr/libexec/msgcollector/msgcollector_shared
   loop_protection

   local fifo="${msgcollector_run_dir}/${identifier}_${progressbaridx}_fifo"
   local progress_txt_file="${msgcollector_run_dir}/${identifier}_${progressbaridx}_progresstxt"

   if [ "$did_echo" = "1" ]; then
      true "did already echo to progress_txt_file"
   else
      did_echo="1"
      safe_file_write "$progress" "$progress_txt_file"
   fi

   if [ -p "${msgcollector_run_dir}/${identifier}_${progressbaridx}_fifo" ]; then
      if [ -f "${msgcollector_run_dir}/${identifier}_${progressbaridx}_yadprogresspid" ]; then
         yad_progress_pid="$(cat "${msgcollector_run_dir}/${identifier}_${progressbaridx}_yadprogresspid")"
         ## Validate PID is numeric before using in ps.
         if ! is_whole_number "$yad_progress_pid"; then
            true "yad_progress_pid is not numeric: $yad_progress_pid"
            return 0
         fi
         ## Check if 'yad' is running.
         local ps_p_exit_code
         ps_p_exit_code="0"
         ps -p "$yad_progress_pid" >/dev/null 2>/dev/null || { ps_p_exit_code="$?"; true; };
         if [ "$ps_p_exit_code" = "0" ]; then
            true "yad is running."
            ## || true to catch an error if the pipe no longer exists.
            safe_file_write "$progress" "$fifo"
            ## Debugging.
            #caller="$(ps -p $PPID)" || true
            #echo "progress: $progress | caller: $PPID | $caller" >> /home/user/progresslog
            return 0
         else
            true "ps_p_exit_code was not 0, was $ps_p_exit_code"
         fi
      else
         true "yadprogresspid does not exist: ${msgcollector_run_dir}/${identifier}_${progressbaridx}_yadprogresspid"
      fi
   else
      true "fifo does not exist: ${msgcollector_run_dir}/${identifier}_${progressbaridx}_fifo"
   fi
   ## XXX
   #progress_bar
   return 0
}

source /usr/libexec/msgcollector/msgcollector_shared
## sets: ${msgcollector_run_dir}
folder_init

## provides: check, is_whole_number
source /usr/libexec/msgcollector/check

parse_cmd_options "$@"

check "$identifier"
check "$progressbaridx"

if [ "$progress" = "" ]; then
   error "Variable 'progress' does not exist"
   exit 1
fi

## Validate that progress is numeric to prevent injection.
if ! is_whole_number "$progress"; then
   error "Variable 'progress' is not numeric: '$progress'"
   exit 1
fi

progress_bar
