#!/usr/bin/env bash
#
# Copyright (c) 2023 darkmaster @grm34
#
# This script automatically translates base language strings and adds
# them into the various translations (original will be used on error).
# It also removes duplicate strings and rearranges them alphabetically.

_sort_strings() {
  # RM duplicate strings from an array and sorts them alphabetically.
  # Usage: _sort_strings "$@" (array of strings)
  # Returns: $sorted_strings (array)
  local string strings
  declare -A strings
  for string in "${@}"; do
    [[ $string ]] && IFS=" " strings["${string:- }"]=1
  done
  # shellcheck disable=SC2207
  IFS=$'\n' sorted_strings=($(sort <<< "${!strings[*]}"))
}

_clean_cfg_files() {
  # RM duplicates lines and sorts them alphabetically.
  # Usage: _clean_cfg_files "$@" (array of files)
  local file
  for file in "$@"; do
    mapfile -t strings < "$file"
    _sort_strings "${strings[@]}"
    printf "%s\n" "${sorted_strings[@]}" > "$file"
  done
}

_get_strings_from_cfg() {
  # Grabs strings from CFG files.
  # Usage: _get_strings_from_cfg "$@" (array of files)
  # Returns: $<language_code>_strings $cfg_list (arrays)
  local file name
  for file in "$@"; do
    name=${file##*/}; name="${name/.cfg/_strings}"
    mapfile -t "$name" < "$file"
    [[ $name != en_strings ]] && cfg_list+=("$name")
  done
}

_get_string_data() {
  # Grabs string name and string value
  # Returns: $data (array)
  IFS=$'\n' read -d "" -ra data <<< "${1//=/$'\n'}"
  data[1]=${data[1]//\"}
}

_translate_string() {
  # Usage: _translate_string "string" "language code"
  # Returns: $translated (string)
  translated="$(curl -s https://api-free.deepl.com/v2/translate \
    -d auth_key=f1414922-db81-5454-67bd-9608cdca44b3:fx \
    -d "text=$1" -d "target_lang=${2^^}" \
    | grep -o '"text":"[^"]*' | grep -o '[^"]*$')"
}

_translate_and_add_missing_strings_into_cfg() {
  # Translates then write missing strings from base language
  # into the various translation files (from $cfg_list).
  local line language trad_strings
  for line in "${en_strings[@]:?}"; do
    _get_string_data "$line"
    for language in "${cfg_list[@]}"; do
      declare -n trad_strings="$language"
      if [[ "${trad_strings[*]}" != *"${data[0]}="* ]]; then
        _translate_string "${data[1]}" "${language/_strings}"
        [[ -n $translated ]] && line="${data[0]}=\"${translated}\""
        [[ -n $translated ]] && note="translated" || note="original"
        trad_strings+=("$line"); file="${language/_strings/.cfg}"
        printf "%s\n" "${trad_strings[@]}" > "lang/$file"
        echo "=> ${data[0]} (${note}) added into $file"
      fi
    done
  done
}

# Run auto-translate.
if [[ $1 == dh ]]; then
  echo "Running auto-translate (this could take a while)..."
  _clean_cfg_files lang/*.cfg
  _get_strings_from_cfg lang/*.cfg
  _translate_and_add_missing_strings_into_cfg
  _clean_cfg_files lang/*.cfg
  [[ $note ]] && echo "==> done" || echo "==> nothing to translate"
else
  echo "ERROR: you must specify 'dh' as argument"
fi

