#!/bin/bash

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

## style-ok: no-strict
##
## UTF-8 locale default (no block "export LC_ALL=C"): these tools process
## Unicode wiki content, so the C byte-locale would break nocasematch,
## "[:space:]" trimming and "grep -i" on non-ASCII. Byte-exact operations
## carry an explicit "LC_ALL=C" prefix instead.
set -o errexit
set -o nounset
set -o errtrace
set -o pipefail
shopt -s inherit_errexit
shopt -s shift_verbose

# shellcheck source=../share/mediawiki-shell/common
source /usr/share/mediawiki-shell/common

log info "START"

usage() {
  printf '%s\n' "Usage: ${0##*/} [OPTIONS] WIKI WIKI_TARGET PAGE_FILE [OUTPUT]
Options:
  --edit-msg=X     Summary to specify for edit
  --dry-run        Preview only; skip the actual upload on the server.
Defaults:
  OUTPUT=todo
Example:
  ${0##*/} 'https://www.kicksecure.com/w' 'https://www.whonix.org/w' File:Search-engine-clipart.jpg
  ${0##*/} 'https://www.kicksecure.com/w' 'https://www.whonix.org/w' File:Search-engine-clipart.jpg ${TMPFOLDER}/File:Search-engine-clipart.jpg" >&2
  exit 1
}

# shellcheck source=../../../helper-scripts/usr/libexec/helper-scripts/parse_opt.sh
source "${HELPER_SCRIPTS_PATH:-}"/usr/libexec/helper-scripts/parse_opt.sh

edit_msg=""

while true; do
  [[ "${1-}" =~ ^- ]] || break
  begin_optparse "${1-}" "${2-}" || break
  true "${opt-}" "${arg-}" "${opt_orig-}"
  case "${opt}" in
    edit-msg)
      get_arg
      edit_msg="${arg}"
      ;;
    dry-run)
      export DRY_RUN="true"
      ;;
    h|help)
      usage
      ;;
    --|"")
      break
      ;;
    *)
      die 2 "Invalid option: '${opt_orig}'"
      ;;
  esac
  shift "${shift_n:-1}"
done

if [[ -z "${3-}" ]]; then
  usage
fi

WIKI_URL="$1"
wiki_url_target="$2"
page_file="$3"
page_file_local="${4-}"

if [ -z "${page_file_local}" ]; then
  log info "default output_file: yes"
  page_file_local="$(set_backup_page_item "${page_file}")"
  output_file="${TMPFOLDER}/${page_file_local}"
  assert_path_within_dir "${TMPFOLDER}" "${output_file}"
else
  log info "default output_file: no"
  output_file="${page_file_local}"
fi

check_vars_exist wiki_url_target page_file

## Defense-in-depth: check page_file for malicious unicode before using
## it to derive the remote upload filename.
printf '%s\n' "${page_file}" | unicode-show

wiki_remote_file_title="$(stecho "${page_file}" | str_replace "File:" "")"

# shellcheck source=../share/mediawiki-shell/wiki-config
source /usr/share/mediawiki-shell/wiki-config

log info "WIKI_URL             : ${WIKI_URL}"
log info "WIKI_API             : ${WIKI_API}"
log info "wiki_url_target      : ${wiki_url_target}"
log info "page_file            : ${page_file}"
log info "page_file_local      : ${page_file_local}"
log info "output_file          : ${output_file}"

#mw-login-test "$WIKI_URL"

log info "Downloading file...: mw-file-download '${WIKI_URL}' '${page_file}' '${output_file}'"
mw-file-download "${WIKI_URL}" "${page_file}" "${output_file}"
log info "Download file success."

## time-of-check to time-of-use TOCTOU
## Check for pending edits only after page was fetched.
## Checking for pending edits before fetching page would leave room for
## making a pending edit after the page has been fetched.
## This ensures that the fetched edit was not pending, i.e. confirmed.
mw-page-pending-check "${WIKI_URL}" "${page_file}"

log info "Uploading file...: mw-file-upload '${wiki_url_target}' '${output_file}' '${wiki_remote_file_title}'"

if [ -n "${edit_msg}" ]; then
  mw-file-upload "${wiki_url_target}" "${output_file}" "${wiki_remote_file_title}" "${edit_msg}"
else
  mw-file-upload "${wiki_url_target}" "${output_file}" "${wiki_remote_file_title}"
fi

log info "Upload file success."
