#!/bin/bash
# DriftwoodXI on Steam Deck / SteamOS / Bazzite handheld
# Proton GE + Ashita + xiloader, zenity login with optional remember
set -euo pipefail

HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Prefer installed copy under DRIFTWOOD_ROOT/bin, else package scripts/
if [ -f "${DRIFTWOOD_ROOT:-}/bin/env.sh" ]; then
  # shellcheck source=/dev/null
  source "${DRIFTWOOD_ROOT}/bin/env.sh"
elif [ -f "$HERE/env.sh" ]; then
  # shellcheck source=/dev/null
  source "$HERE/env.sh"
else
  echo "env.sh not found" >&2
  exit 1
fi

PREFIX="$DRIFTWOOD_PREFIX"
R="$DRIFTWOOD_PROTON"
WINE="$DRIFTWOOD_WINE"
ASHITA="$DRIFTWOOD_ASHITA"
INI="$DRIFTWOOD_INI"
CFG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/driftwoodxi"
USER_FILE="$CFG_DIR/username"
SECRET_SERVICE="driftwoodxi"
SECRET_ACCOUNT="login"

if [ ! -x "$WINE" ]; then
  echo "Proton wine not found at: $WINE" >&2
  echo "Install GE-Proton11-5 under ~/.local/share/Steam/compatibilitytools.d/" >&2
  exit 1
fi
if [ ! -f "$ASHITA/Ashita-cli.exe" ]; then
  echo "Ashita not found at: $ASHITA" >&2
  exit 1
fi

export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
export DISPLAY="${DISPLAY:-:0}"
if [ -z "${XAUTHORITY:-}" ]; then
  for cand in "$XDG_RUNTIME_DIR"/xauth_* "$HOME/.Xauthority"; do
    [ -f "$cand" ] || continue
    XAUTHORITY="$cand"
    break
  done
  export XAUTHORITY
fi

mkdir -p "$CFG_DIR"
chmod 700 "$CFG_DIR"

load_saved_user() {
  if [ -f "$USER_FILE" ]; then
    tr -d '\r\n' < "$USER_FILE"
  fi
}

load_saved_pass() {
  secret-tool lookup service "$SECRET_SERVICE" account "$SECRET_ACCOUNT" 2>/dev/null || true
}

save_credentials() {
  local user="$1" pass="$2"
  printf '%s\n' "$user" > "$USER_FILE"
  chmod 600 "$USER_FILE"
  if printf '%s' "$pass" | secret-tool store --label="DriftwoodXI" service "$SECRET_SERVICE" account "$SECRET_ACCOUNT" 2>/dev/null; then
    return 0
  fi
  local pass_file="$CFG_DIR/password"
  printf '%s\n' "$pass" > "$pass_file"
  chmod 600 "$pass_file"
  if command -v zenity >/dev/null; then
    zenity --warning --title="DriftwoodXI" --width=420 \
      --text="Saved password under ~/.config/driftwoodxi/ (keyring unavailable).\nUnlock KWallet for better storage." || true
  fi
}

clear_credentials() {
  rm -f "$USER_FILE" "$CFG_DIR/password"
  secret-tool clear service "$SECRET_SERVICE" account "$SECRET_ACCOUNT" 2>/dev/null || true
}

prompt_login_gui() {
  local saved_user="$1"
  local user pass
  user="$(zenity --entry --title="DriftwoodXI" --width=420 \
    --text="Username" --entry-text="$saved_user" \
    --ok-label="Next" --cancel-label="Cancel" 2>/dev/null)" || return 1
  user="$(printf '%s' "$user" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
  [ -n "$user" ] || { zenity --error --title="DriftwoodXI" --text="Username is required." || true; return 1; }

  pass="$(zenity --password --title="DriftwoodXI" --ok-label="Next" --cancel-label="Cancel" 2>/dev/null)" || return 1
  [ -n "$pass" ] || { zenity --error --title="DriftwoodXI" --text="Password is required." || true; return 1; }

  DRIFTWOOD_USER="$user"
  DRIFTWOOD_PASS="$pass"

  if zenity --question --title="DriftwoodXI" --width=420 \
    --ok-label="Remember" --cancel-label="Do not save" \
    --text="Remember username and password on this device?" 2>/dev/null; then
    save_credentials "$DRIFTWOOD_USER" "$DRIFTWOOD_PASS"
  else
    clear_credentials
  fi
  return 0
}

if [ -z "${DRIFTWOOD_USER:-}" ] || [ -z "${DRIFTWOOD_PASS:-}" ]; then
  SAVED_USER="$(load_saved_user)"
  SAVED_PASS="$(load_saved_pass)"
  if [ -z "$SAVED_PASS" ] && [ -f "$CFG_DIR/password" ]; then
    SAVED_PASS="$(tr -d '\r\n' < "$CFG_DIR/password")"
  fi

  if [ -n "${DRIFTWOOD_USER:-}" ] && [ -z "${DRIFTWOOD_PASS:-}" ] && [ "$DRIFTWOOD_USER" = "$SAVED_USER" ] && [ -n "$SAVED_PASS" ]; then
    DRIFTWOOD_PASS="$SAVED_PASS"
  fi

  if [ -z "${DRIFTWOOD_USER:-}" ] && [ -z "${DRIFTWOOD_PASS:-}" ] && [ -n "$SAVED_USER" ] && [ -n "$SAVED_PASS" ]; then
    if zenity --question --title="DriftwoodXI" --width=420 \
      --ok-label="Play" --cancel-label="Change account" \
      --text="Play as <b>$SAVED_USER</b>?" 2>/dev/null; then
      DRIFTWOOD_USER="$SAVED_USER"
      DRIFTWOOD_PASS="$SAVED_PASS"
    else
      if ! prompt_login_gui "$SAVED_USER"; then
        exit 0
      fi
    fi
  fi

  if [ -z "${DRIFTWOOD_USER:-}" ] || [ -z "${DRIFTWOOD_PASS:-}" ]; then
    if [ -n "${DISPLAY:-}" ] && command -v zenity >/dev/null; then
      if ! prompt_login_gui "${SAVED_USER:-}"; then
        exit 0
      fi
    else
      if [ -z "${DRIFTWOOD_USER:-}" ]; then
        read -rp "DriftwoodXI username: " DRIFTWOOD_USER
      fi
      if [ -z "${DRIFTWOOD_PASS:-}" ]; then
        read -rs -p "DriftwoodXI password: " DRIFTWOOD_PASS; echo
      fi
    fi
  fi
fi

for PID in $(pgrep -f "xiloader.exe --server" 2>/dev/null || true) $(pgrep -x wineserver 2>/dev/null || true) $(pgrep -x winedevice.exe 2>/dev/null || true); do
  [ -n "$PID" ] || continue
  kill -9 "$PID" 2>/dev/null || true
done
sleep 1

if [ -n "${DISPLAY:-}" ] && command -v zenity >/dev/null && [ "${DRIFTWOOD_SKIP_CONFIRM:-}" != "1" ]; then
  if ! zenity --question --title="DriftwoodXI" --width=420 \
    --ok-label="Start" --cancel-label="Cancel" \
    --text="Start DriftwoodXI as:\n\n<b>$DRIFTWOOD_USER</b>" 2>/dev/null; then
    exit 0
  fi
fi

mkdir -p "$ASHITA/config/boot"
python3 - "$ASHITA/config/boot/$INI" "$DRIFTWOOD_USER" "$DRIFTWOOD_PASS" \
  "$DRIFTWOOD_SERVER" "$DRIFTWOOD_SCRIPT" \
  "$DRIFTWOOD_WIDTH" "$DRIFTWOOD_HEIGHT" \
  "$DRIFTWOOD_PADMODE" "$DRIFTWOOD_PADSIN" <<'PY'
from pathlib import Path
import sys
path, user, pw, server, script, w, h, padmode, padsin = sys.argv[1:10]
path = Path(path)
path.write_text(
    "; DriftwoodXI profile (generated by play.sh)\n"
    "[ashita.launcher]\n"
    "autoclose=1\n"
    "name=DriftwoodXI - Default\n"
    "[ashita.boot]\n"
    "file=.\\bootloader\\xiloader.exe\n"
    f"script={script}\n"
    "gamemodule=ffximain.dll\n"
    f"command=--server {server} --user {user} --pass {pw}\n"
    "args=\n"
    "[ffxi.registry]\n"
    f"; Window/background/menu {w}x{h} (FFXI-supported; avoid 1280x800)\n"
    f"0001={w}\n"
    f"0002={h}\n"
    f"0003={w}\n"
    f"0004={h}\n"
    f"0037={w}\n"
    f"0038={h}\n"
    "0034=1\n"
    "; Xbox 360 / Alternate Setup E (XInput)\n"
    f"padmode000={padmode}\n"
    f"padsin000={padsin}\n"
    "[ashita.input]\n"
    "gamepad.allowbackground=1\n"
    "gamepad.disableenumeration=0\n"
    "keyboard.blockinput=0\n"
    "keyboard.blockbindsduringinput=0\n"
    "keyboard.silentbinds=0\n"
    "keyboard.windowskeyenabled=1\n"
    "mouse.blockinput=0\n"
    "mouse.unhook=0\n"
    "[ashita.fonts]\n"
    "d3d8.disable_scaling=0\n"
    "d3d8.family=Arial\n"
    "d3d8.height=10\n"
    "[ashita.logging]\n"
    "level=5\n"
)
PY

export WINEPREFIX="$PREFIX"
export WINEARCH=win64
export WINEDEBUG=-all
export WINEESYNC=1 WINEFSYNC=1
export WINEDLLOVERRIDES="winemenubuilder=d;d3d8=b"
export LD_LIBRARY_PATH="$R/lib:$R/lib/x86_64-linux-gnu:$R/lib/i386-linux-gnu:$R/lib/wine/x86_64-unix:$R/lib/wine/i386-unix"
export WINEDLLPATH="$R/lib/wine/i386-windows:$R/lib/wine/x86_64-windows"

"$WINE" reg add "HKLM\\SOFTWARE\\WOW6432Node\\PlayOnlineUS\\InstallFolder" /v 0001 /t REG_SZ /d "C:\\Program Files (x86)\\PlayOnline\\SquareEnix\\FINAL FANTASY XI\\" /f >/dev/null 2>&1 || true
"$WINE" reg add "HKLM\\SOFTWARE\\WOW6432Node\\PlayOnlineUS\\InstallFolder" /v 1000 /t REG_SZ /d "C:\\Program Files (x86)\\PlayOnline\\SquareEnix\\PlayOnlineViewer" /f >/dev/null 2>&1 || true
POL='C:\Program Files (x86)\PlayOnline\SquareEnix\PlayOnlineViewer\viewer\com\polcore.dll'
FFXI='C:\Program Files (x86)\PlayOnline\SquareEnix\FINAL FANTASY XI\FFXi.dll'
"$WINE" reg add "HKLM\\SOFTWARE\\WOW6432Node\\Classes\\CLSID\\{3501f5dd-7894-42df-866a-a2b6527d8049}\\InprocServer32" /ve /t REG_SZ /d "$POL" /f >/dev/null 2>&1 || true
"$WINE" reg add "HKLM\\SOFTWARE\\WOW6432Node\\Classes\\CLSID\\{989D790D-6236-11D4-80E9-00105A81E890}\\InprocServer32" /ve /t REG_SZ /d "$FFXI" /f >/dev/null 2>&1 || true
K="HKLM\\SOFTWARE\\WOW6432Node\\PlayOnlineUS\\SquareEnix\\FinalFantasyXI"
"$WINE" reg add "$K" /v 0001 /t REG_DWORD /d "$DRIFTWOOD_WIDTH" /f >/dev/null 2>&1 || true
"$WINE" reg add "$K" /v 0002 /t REG_DWORD /d "$DRIFTWOOD_HEIGHT" /f >/dev/null 2>&1 || true
"$WINE" reg add "$K" /v 0003 /t REG_DWORD /d "$DRIFTWOOD_WIDTH" /f >/dev/null 2>&1 || true
"$WINE" reg add "$K" /v 0004 /t REG_DWORD /d "$DRIFTWOOD_HEIGHT" /f >/dev/null 2>&1 || true
"$WINE" reg add "$K" /v 0037 /t REG_DWORD /d "$DRIFTWOOD_WIDTH" /f >/dev/null 2>&1 || true
"$WINE" reg add "$K" /v 0038 /t REG_DWORD /d "$DRIFTWOOD_HEIGHT" /f >/dev/null 2>&1 || true
"$WINE" reg add "$K" /v 0034 /t REG_DWORD /d 1 /f >/dev/null 2>&1 || true
"$WINE" reg add "$K" /v padmode000 /t REG_SZ /d "$DRIFTWOOD_PADMODE" /f >/dev/null 2>&1 || true
"$WINE" reg add "$K" /v padsin000 /t REG_SZ /d "$DRIFTWOOD_PADSIN" /f >/dev/null 2>&1 || true

echo "==> booting DriftwoodXI as $DRIFTWOOD_USER (log: /tmp/driftwood-console.log)"
cd "$ASHITA"
WINEDEBUG=-all "$WINE" Ashita-cli.exe "$INI" 2>&1 | tee /tmp/driftwood-console.log

python3 - "$ASHITA/config/boot/$INI" <<'PY'
from pathlib import Path
import re
p = Path(__import__("sys").argv[1])
s = p.read_text(errors="ignore")
s = re.sub(r" --user \S+ --pass \S+", "", s, count=1)
p.write_text(s)
PY
