#!/usr/bin/env bash
# publish-launcher.sh — publish a Velopack release of the Metin2 launcher.
#
# Drives `dotnet publish` + `vpk pack` to produce a win-x64 Velopack release
# and (optionally) rsyncs it to updates.jakubkadlec.dev/launcher/ so the
# launcher's Velopack self-update flow can pick it up on the next run.
#
# See README.md -> "Publishing a release" for the operator runbook.
#
# Usage:
#   scripts/publish-launcher.sh --version 0.1.0 [--dry-run] [--yes] \
#       [--rsync-target <user@host:/path>]
#
# Known limitation (2026-04-14):
#   Velopack's `vpk pack` command is platform-routed. Running on Linux only
#   produces a .AppImage bundle; building a win-x64 NuGet release requires a
#   Windows host. Until we have a Windows CI runner this script is only
#   usable on a Windows machine. Running --dry-run on Linux will hit the
#   error "Required command was not provided" or "Unrecognized command or
#   argument 'windows'" from vpk itself. The dotnet publish step still works
#   on Linux and is a useful sanity check.
set -euo pipefail

VERSION=""
DRY_RUN=0
YES=0
RSYNC_TARGET="mt2.jakubkadlec.dev@mt2.jakubkadlec.dev:/var/www/updates.jakubkadlec.dev/launcher/"

die() { echo "error: $*" >&2; exit 1; }
say() { echo "[publish-launcher] $*"; }

while [[ $# -gt 0 ]]; do
    case "$1" in
        --version)       VERSION="$2"; shift 2 ;;
        --rsync-target)  RSYNC_TARGET="$2"; shift 2 ;;
        --dry-run)       DRY_RUN=1; shift ;;
        --yes)           YES=1; shift ;;
        -h|--help)       sed -n '1,25p' "$0"; exit 0 ;;
        *) die "unknown arg: $1" ;;
    esac
done

[[ -n "$VERSION" ]] || die "--version is required"

REPO_ROOT=$(cd "$(dirname "$0")/.." && pwd)
CSPROJ="$REPO_ROOT/src/Metin2Launcher/Metin2Launcher.csproj"
PUBLISH_DIR="$REPO_ROOT/src/Metin2Launcher/bin/Release/net8.0/win-x64/publish"
OUTPUT_DIR="$REPO_ROOT/release-velopack"

[[ -f "$CSPROJ" ]] || die "csproj not found: $CSPROJ"

# Ensure vpk is on PATH, install if missing.
if ! command -v vpk >/dev/null 2>&1; then
    if ! dotnet tool list --global 2>/dev/null | awk '{print $1}' | grep -qx 'vpk'; then
        say "installing vpk global tool..."
        dotnet tool install --global vpk
    fi
    export PATH="$HOME/.dotnet/tools:$PATH"
fi
command -v vpk >/dev/null 2>&1 || die "vpk still not on PATH after install"

say "version: $VERSION"
say "repo:    $REPO_ROOT"

# ---- [1/3] dotnet publish ----
say "[1/3] dotnet publish -c Release -r win-x64 --self-contained"
dotnet publish "$CSPROJ" \
    -c Release \
    -r win-x64 \
    --self-contained \
    -p:PublishSingleFile=true \
    -p:IncludeNativeLibrariesForSelfExtract=true

[[ -d "$PUBLISH_DIR" ]] || die "publish output dir missing: $PUBLISH_DIR"
[[ -f "$PUBLISH_DIR/Metin2Launcher.exe" ]] || die "Metin2Launcher.exe not in publish output"

# ---- [2/3] vpk pack ----
say "[2/3] vpk pack --packId Metin2Launcher --packVersion $VERSION --channel win-x64"
mkdir -p "$OUTPUT_DIR"
vpk pack \
    --packId Metin2Launcher \
    --packVersion "$VERSION" \
    --packDir "$PUBLISH_DIR" \
    --outputDir "$OUTPUT_DIR" \
    --channel win-x64 \
    --mainExe Metin2Launcher.exe

say "  output: $OUTPUT_DIR"
ls -la "$OUTPUT_DIR" || true

# Sanity check: expect a RELEASES manifest and at least one .nupkg.
if ! ls "$OUTPUT_DIR"/RELEASES* >/dev/null 2>&1; then
    die "vpk pack produced no RELEASES file in $OUTPUT_DIR"
fi
if ! ls "$OUTPUT_DIR"/*.nupkg >/dev/null 2>&1; then
    die "vpk pack produced no .nupkg in $OUTPUT_DIR"
fi

# ---- [3/3] rsync ----
if [[ "$DRY_RUN" -eq 1 ]]; then
    say "[3/3] --dry-run set, skipping rsync. target would be: $RSYNC_TARGET"
    exit 0
fi

say "[3/3] rsync target: $RSYNC_TARGET"
if [[ "$YES" -ne 1 ]]; then
    read -r -p "continue? [y/N] " ans
    [[ "$ans" == "y" || "$ans" == "Y" ]] || die "aborted by user"
fi

rsync -av --checksum --omit-dir-times --no-perms \
    "$OUTPUT_DIR"/ "$RSYNC_TARGET"

say "done."
