#!/bin/bash

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

set -o errexit
set -o nounset
set -o errtrace
set -o pipefail
shopt -s inherit_errexit
shopt -s shift_verbose
export LC_ALL=C
## style-ok: no-tmp-hardcode -- /tmp appears only in usage() example paths.

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

usage() {
  printf '%s\n' "Usage: ${0##*/} [--dry-run] WIKI INPUT PAGE [EDIT_MSG]
Options:
  --dry-run        Preview only; skip the actual edit on the server.
Defaults:
  EDIT_MSG=${default_edit_msg}
Example:
  ${0##*/} 'https://www.kicksecure.com/w' /tmp/a About" >&2
  exit 1
}

default_edit_msg="mediawiki-shell-bot-default-edit-message"

while true; do
  case "${1-}" in
    --dry-run)
      export DRY_RUN="true"
      shift
      ;;
    -h|--help)
      usage
      ;;
    --)
      shift
      break
      ;;
    -*)
      die 2 "Invalid option: '$1'"
      ;;
    *)
      break
      ;;
  esac
done

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

WIKI_URL="$1"
new_file="$2"
page_title="$3"
edit_msg="${4-"${default_edit_msg}"}"

check_vars_exist new_file page_title

## Defense-in-depth: check page_title for malicious unicode before
## sending it to the wiki API.
printf '%s\n' "${page_title}" | unicode-show

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

if [ -d "${new_file}" ]; then
  die 1 "new_file '${new_file}' is a folder!"
fi

if [ ! -r "${new_file}" ]; then
  die 2 "Local file '${new_file}' does not exist or is not readable!"
fi

if [ ! -s "${new_file}" ]; then
  log info "Local file '${new_file}' was empty."
  exit 0
fi

log info "Editing page '${WIKI_URL}' | '${WIKI_API}' | '${page_title}'..."
#log info "Fetching edit token..."

mw-login-test "${WIKI_URL}"

curl_run \
  "${curl_opts[@]}" \
  --cookie "${cookie_jar}" \
  --cookie-jar "${cookie_jar}" \
  --header "Accept-Language: en-GB" \
  --header "Connection: keep-alive" \
  --compressed \
  --output "${TMPFOLDER}/fetch-edit-token.json" \
  --request "GET" \
  "${WIKI_API}?action=query&meta=tokens&format=json"

csrf_token=$(jq --raw-output '.query.tokens.csrftoken' -- "${TMPFOLDER}/fetch-edit-token.json")

if [ "${#csrf_token}" = 42 ]; then
  log info "Edit token for page OK."
else
  die 1 "Edit token for page not set."
fi

#log info "Editing '$page_title'..."

## XXX
## &tags=mediawiki-shell
## Need to create wiki tag mediawiki-shell here:
## https://www.whonix.org/wiki/Special:Tags

dry_run_skip "edit page '${page_title}' on '${WIKI_URL}'"

curl_run \
  "${curl_opts[@]}" \
  --cookie "${cookie_jar}" \
  --cookie-jar "${cookie_jar}" \
  --header "Accept-Language: en-GB" \
  --header "Connection: keep-alive" \
  --header "Expect:" \
  --data-urlencode "title=${page_title}" \
  --data-urlencode "text@${new_file}" \
  --data-urlencode "token=${csrf_token}" \
  --data-urlencode "summary=${edit_msg}" \
  --output "${TMPFOLDER}/edit-result.json" \
  --request "POST" \
  "${WIKI_API}?action=edit&format=json&tags=mediawiki-shell&bot"

log info "Network for edit page ok."

test -r "${TMPFOLDER}/edit-result.json"

## FIXME: Sanitizing JSON before handing to jq is prohibited, see Bash
## style guide rule R-140. Sanitize after parsing with jq.
edit_result_output="$(stcat "${TMPFOLDER}/edit-result.json")"

edit_result_jq="$(jq -r ".edit.result" <<<"${edit_result_output}")"

if [ "${edit_result_jq}" = "Success" ]; then
  log info "Edit page success."
  exit 0
fi

jq . <<<"${edit_result_output}" | stcat >&2
die 1 "Edit page error."
