#!/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

# 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] [OUTPUT_DIR]
Options:
  --continue-from-page=N      Continue from page index
  --multiwiki-category=X      Category of multiwiki (default: ${default_multiwiki_category})
  --multiwiki-extra-pages=X   Extra multiwiki pages to append
Defaults:
  WIKI=${default_wiki_url}
  WIKI_TARGET=${default_wiki_url_target}
  OUTPUT_DIR=${default_output_dir}
Example:
  ${0##*/}
  ${0##*/} ${default_wiki_url}
  ${0##*/} ${default_wiki_url} ${default_wiki_url_target}
  ${0##*/} ${default_wiki_url} ${default_wiki_url_target} ${default_output_dir}" >&2
  exit 1
}

# shellcheck source=/usr/libexec/helper-scripts/parse_opt.sh
source /usr/libexec/helper-scripts/parse_opt.sh

default_wiki_url="https://www.kicksecure.com/w"
default_wiki_url_target="https://www.whonix.org/w"
default_output_dir="$HOME/mediawiki-shell/mirror-multi-wiki"

default_multiwiki_category="MultiWiki"
continue_from_page=""
multiwiki_extra_pages=""

while true; do
  [[ "${1-}" =~ ^- ]] || break
  begin_optparse "${1:-}" "${2:-}" || break
  true "${opt-}" "${arg-}" "${opt_orig-}"
  case "${opt}" in
    continue-from-page) get_arg; continue_from_page="${arg}";;
    multiwiki-category) get_arg; multiwiki_category="${arg}";;
    multiwiki-extra-pages) get_arg; multiwiki_extra_pages="${arg}";;
    h|help) usage;;
    --|"") break;;
    *) die 2 "Invalid option: '${opt_orig}'"
  esac
  shift "${shift_n:-1}"
done

multiwiki_category="${multiwiki_category-"${default_multiwiki_category}"}"
edit_msg='mediawiki-shell-bot-mirror-multi-wiki-page-from-kicksecure-to-whonix'

WIKI_URL="${1-"${default_wiki_url}"}"
wiki_url_target="${2-"${default_wiki_url_target}"}"
output_dir="${3-"${default_output_dir}"}"

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

allpages_file="${TMPFOLDER}/allpages.txt"
safe-rm -f -- "$allpages_file"

log info "TMPFOLDER            : $TMPFOLDER"
log info "WIKI_URL             : $WIKI_URL"
log info "WIKI_API             : $WIKI_API"
log info "allpages_file        : $allpages_file"
log info "multiwiki_category   : $multiwiki_category"
log info "multiwiki_extra_pages: $multiwiki_extra_pages"

mkdir --parents -- "$output_dir"

if ! test -d "$output_dir"; then
  log error "output_dir '$output_dir' does not exist! Run...?:"
  stecho "mkdir --parents -- '$output_dir'"
  die 1 "Cannot continue."
fi

if ! test -w "$output_dir"; then
  log error "output_dir '$output_dir' unwritable! Run...?:"
  stecho "chown --recursive -- '$USER:$USER' '$output_dir'"
  die 1 "Cannot continue."
fi

mw-login-test "$WIKI_URL"

all_pages="$(
  $curl \
    "${curl_opts[@]}" \
    "${WIKI_API}?action=query&format=json&list=categorymembers&cmtitle=Category:$multiwiki_category&cmlimit=500"
)"

## TODO: cmcontinue
#https://www.kicksecure.com/w/api.php?action=query&format=json&list=categorymembers&cmtitle=Category:MultiWiki&cmcontinue=page|434f444553454c454354|748

for multiwiki_extra_pages_item in $multiwiki_extra_pages; do
  stecho "$multiwiki_extra_pages_item" | tee -a -- "$allpages_file" >/dev/null
done

stecho "$all_pages" | jq -r ".query.categorymembers[] | .title | @sh" | tee -a -- "$allpages_file" >/dev/null

test -f "$allpages_file"
if [ ! -s "$allpages_file" ]; then
  die 1 "allpages_file file is empty!"
fi
counter_total="$(awk 'END {print NR}' "$allpages_file")"

## mw-multi-wiki --continue-from-page="Template:VM"
continue_next=no
if [ -z "$continue_from_page" ]; then
  continue_next=yes
fi

counter_currently=0
while IFS=$'\n' read -r item_from_all_pages; do
  (( counter_currently++ )) || true

  backup_page_item="$item_from_all_pages"
  ## 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="$(stecho "$backup_page_item" | str_replace "$search" "$replace")"

  log info "PAGE | $counter_currently / $counter_total | $item_from_all_pages | $backup_page_item"

  if [ "${backup_page_item,,}" = "${continue_from_page,,}" ]; then
    continue_next=yes
  fi
  if [ "$continue_next" = "no" ]; then
    continue
  fi

  copy_wiki_pages_exit_code=0

  TMPFOLDER="$TMPFOLDER" \
    mw-copy-wiki-pages "--edit-msg=${edit_msg}" "$WIKI_URL" "$wiki_url_target" "$backup_page_item" \
      || copy_wiki_pages_exit_code="$?"

  case "$copy_wiki_pages_exit_code" in
    10)
      log warn "PAGE - Skipped backup_page_item '$backup_page_item' because of pending edits."
      ;;
    0)
      log info "PAGE - backup_page_item '$backup_page_item' mirroring success."
      ;;
    *)
      die 1 "PAGE - backup_page_item '$backup_page_item' mirroring error! copy_wiki_pages_exit_code: '$copy_wiki_pages_exit_code'"
      ;;
  esac

  if ! stecho "$backup_page_item" | grep --ignore-case -- "File:" >/dev/null 2>&1; then
    log info "FILE | No, not a file, ok."
    continue
  fi

  log info "FILE | $counter_currently / $counter_total | $item_from_all_pages | $backup_page_item"

  copy_wiki_file_exit_code=0

  TMPFOLDER="$TMPFOLDER" \
    mw-copy-wiki-file "--edit-msg=${edit_msg}" "$WIKI_URL" "$wiki_url_target" "$backup_page_item" \
      || copy_wiki_file_exit_code="$?"

  case "$copy_wiki_file_exit_code" in
    10)
      log warn "FILE - Skipped backup_page_item '$backup_page_item' because of pending edits."
      ;;
    0)
      log info "FILE - backup_page_item '$backup_page_item' mirroring success."
      ;;
    *)
      die 1 "FILE - backup_page_item '$backup_page_item' mirroring error! copy_wiki_file_exit_code: '$copy_wiki_file_exit_code'"
      ;;
  esac

  continue

done <"$allpages_file"
