#!/bin/bash

#set -x
set -e
set -o pipefail
set -o nounset

if ! command -v retry >/dev/null ; then
   echo "ERROR: 'retry' command unavailable! Probably 'retry' package is not installed." >&2
fi

check_vars_exist() {
  for var_name in "$@"; do
    if [ -z "${!var_name+x}" ]; then
      echo "ERROR: Variable '$var_name' is not set or is empty." >&2
      exit 1
    fi
  done
}

missing_variable() {
   echo "$0: ERROR: MISSING VARIABLE: $@"
   exit 1
}

error_output() {
   [[ -v 1 ]] || 1="unset"

   [[ -v WIKI_INDEX ]] || WIKI_INDEX=""
   [[ -v TITLE ]] || TITLE=""
   [[ -v BASH_COMMAND ]] || BASH_COMMAND=""
   [[ -v counter_chunk ]] || counter_chunk="unset"
   [[ -v counter_currently ]] || counter_currently="unset"
   [[ -v TMPFOLDER ]] || TMPFOLDER="unset"
   echo "error_msg: '$1'
WIKI_INDEX: '$WIKI_INDEX'
TITLE: '$TITLE'
TMPFOLDER: '$TMPFOLDER'
counter_chunk: '$counter_chunk'
counter_currently: '$counter_currently'
###" >&2
}

error_handler() {
   last_exit_code="$?"
   echo "###
$0: ERROR:
BASH_COMMAND: '$BASH_COMMAND'
failed with exit code '$last_exit_code'." >&2

   error_output "called-by-error_handler"

   exit 1
}

trap error_handler ERR

exit_handler() {
   local exit_code=$?
   if [ "$exit_code" = "0" ]; then
      echo "## $0: END: with OK exit code: '$exit_code'"
   else
      echo "## $0: END: with ERROR exit code: '$exit_code'"
   fi
   exit "$exit_code"
}

set_curl_binary_default() {
   if command -v scurl &>/dev/null ; then
      curl=scurl
   else
      curl=curl
   fi
}

set_backup_page_item() {
   local backup_page_item search replace

   backup_page_item="$1"

   if [ "$backup_page_item" = "" ]; then
      error "set_backup_filename_item is empty!"
   fi

   ## remove last letter ("'")
   backup_page_item="${backup_page_item::-1}"
   ## remove first letter ("'")
   backup_page_item="${backup_page_item:1}"

   search="'\''"
   replace="'"
   backup_page_item=$(echo "$backup_page_item" | str_replace "$search" "$replace")

   search="&"
   replace="%26"
   backup_page_item=$(echo "$backup_page_item" | str_replace "$search" "$replace")

   ## Same format as git-mediawiki: replace ' ' with '_'.
   ## Replace spaces with underscore.
   search=" "
   replace="_"
   backup_page_item=$(echo "$backup_page_item" | str_replace "$search" "$replace")

   echo "$backup_page_item"
}

set_backup_filename_item() {
   local backup_filename_item search replace

   backup_filename_item="$1"

   if [ "$backup_filename_item" = "" ]; then
      error "backup_filename_item is empty!"
   fi

   ## Same format as git-mediawiki: replace '/' with '%2F'.
   ## Also the file system does not accept files containing '/'.
   search="/"
   replace="%2F"
   backup_filename_item=$(echo "$backup_filename_item" | str_replace "$search" "$replace")

   ## Same format as git-mediawiki: add '.mw' file extension.
   backup_filename_item="${backup_filename_item}.mw"

   echo "$backup_filename_item"
}

curl_get_output_parameter() {
   local loop_counter
   loop_counter=0

   while true ; do
      loop_counter=$(( loop_counter + 1 ))
      if [ "$loop_counter" -ge 50 ]; then
         error "loop_max reached!"
         exit 1
      fi
      case $1 in
         --output)
            output_file="$2"
            shift 2
            break
            ;;
         *)
            shift
            ;;
      esac
   done
}

curl_run() {
   ## Do not destroy "$@" in this function. Therefore passing it to a different
   ## helper function so it stays local there and unchanged here.
   curl_get_output_parameter "$@"

   if [ -z "$output_file" ]; then
      error "output_file is empty!"
      exit 1
   fi

   rm -f "$output_file"
   touch "$output_file"

   local args url encoded_url
   url="${@: -1}"

   [[ -v curl_run_no_encode ]] || curl_run_no_encode=""

   if [ "$curl_run_no_encode" = "true" ]; then
      encoded_url="$url"
   else
      encoded_url="$(mw-urlencode "$url")"
   fi

   # Rebuild the arguments excluding the last parameter, then append the encoded URL
   args=("${@:1:$#-1}" "$encoded_url")

   curl_exit_code=0

   # Run curl with the modified arguments
   $curl "${args[@]}" || { curl_exit_code=$?; true; }

   if [ ! "$curl_exit_code" = "0" ]; then
      echo "$0: ERROR: curl result failed with exit code '$curl_exit_code'. output_file: $output_file" >&2
      cat "$output_file" >&2
      exit 1
   fi
}

log_run() {
   echo "$0 running: $@"
   "$@"
}

log_run_background() {
   echo "$0 running: $@ &"
   "$@" &
   pid="$!"
}

trap exit_handler EXIT

[[ -v TMPFOLDER ]] || TMPFOLDER=~/mediawiki-shell-temp
[[ -v USERDOMAIN ]] || USERDOMAIN=""
[[ -v cookie_jar ]] || cookie_jar="$TMPFOLDER/wiki-cookiejar"
[[ -v curl ]] || set_curl_binary_default
[[ -v curl_opts ]] || curl_opts="\
   --fail \
   --no-progress-meter \
   --show-error \
   --retry-connrefused \
   --retry 10 \
   --retry-delay 5 \
   --cookie nocache=true \
   --user-agent mediawiki-shell \
"

mkdir --parents "$TMPFOLDER"
chmod og-rw "$TMPFOLDER"
