#!/usr/bin/env bash
# ── setup.sh ────────────────────────────────────────────────────────────────
# DragonX Wallet — Development Environment Setup
# Copyright 2024-2026 The Hush Developers
# Released under the GPLv3
#
# Detects your OS/distro, installs build prerequisites, fetches libraries,
# and validates the environment so you can build immediately with:
#
#   ./build.sh                  # dev build
#   ./build.sh --win-release    # Windows cross-compile
#   ./build.sh --linux-release  # Linux release + AppImage
#
# Usage:
#   ./setup.sh                  # Interactive — install everything needed
#   ./setup.sh --check          # Just report what's missing, don't install
#   ./setup.sh --all            # Install dev + all cross-compile targets
#   ./setup.sh --win            # Also install Windows cross-compile deps
#   ./setup.sh --mac            # Also install macOS cross-compile deps
#   ./setup.sh --sapling        # Also download Sapling params (~51 MB)
#   ./setup.sh -j6              # Use 6 threads for building
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail

PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# ── Parallel builds ─────────────────────────────────────────────────────────
# Default to 1 core; use -jN to increase (e.g. -j6)
NPROC=1

# ── Colours ──────────────────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'

ok()    { echo -e "  ${GREEN}✓${NC} $1"; }
miss()  { echo -e "  ${RED}✗${NC} $1"; }
skip()  { echo -e "  ${YELLOW}—${NC} $1"; }
info()  { echo -e "${GREEN}[*]${NC} $1"; }
warn()  { echo -e "${YELLOW}[!]${NC} $1"; }
err()   { echo -e "${RED}[ERROR]${NC} $1"; }
header(){ echo -e "\n${CYAN}── $1 ──${NC}"; }

# ── Parse args ───────────────────────────────────────────────────────────────
CHECK_ONLY=false
SETUP_WIN=false
SETUP_MAC=false
SETUP_SAPLING=false

while [[ $# -gt 0 ]]; do
    case $1 in
        --check)    CHECK_ONLY=true;    shift ;;
        --win)      SETUP_WIN=true;     shift ;;
        --mac)      SETUP_MAC=true;     shift ;;
        --sapling)  SETUP_SAPLING=true; shift ;;
        --all)      SETUP_WIN=true; SETUP_MAC=true; SETUP_SAPLING=true; shift ;;
        -j*)        NPROC="${1#-j}"; shift ;;
        -h|--help)
            sed -n '2,/^# ─\{10\}/{ /^# ─\{10\}/d; s/^# \?//p; }' "$0"
            exit 0
            ;;
        *) err "Unknown option: $1"; exit 1 ;;
    esac
done

# Apply parallel build flag (after arg parsing so -jN override takes effect)
# NOTE: We do NOT export MAKEFLAGS globally — that interferes with autotools
# builds (dragonx daemon). Instead, -j is passed explicitly where needed.

# ── Detect OS / distro ──────────────────────────────────────────────────────
detect_os() {
    OS="$(uname -s)"
    DISTRO="unknown"
    PKG=""

    case "$OS" in
        Linux)
            if [[ -f /etc/os-release ]]; then
                . /etc/os-release
                case "${ID:-}" in
                    ubuntu|debian|linuxmint|pop|elementary|zorin|neon)
                        DISTRO="debian"; PKG="apt" ;;
                    fedora|rhel|centos|rocky|alma)
                        DISTRO="fedora"; PKG="dnf" ;;
                    arch|manjaro|endeavouros|garuda)
                        DISTRO="arch"; PKG="pacman" ;;
                    opensuse*|suse*)
                        DISTRO="suse"; PKG="zypper" ;;
                    void)
                        DISTRO="void"; PKG="xbps" ;;
                    gentoo)
                        DISTRO="gentoo"; PKG="emerge" ;;
                    *)
                        # Fallback: check for package managers
                        command -v apt    &>/dev/null && { DISTRO="debian"; PKG="apt"; } ||
                        command -v dnf    &>/dev/null && { DISTRO="fedora"; PKG="dnf"; } ||
                        command -v pacman &>/dev/null && { DISTRO="arch";   PKG="pacman"; } ||
                        true
                        ;;
                esac
            fi
            ;;
        Darwin)
            DISTRO="macos"
            if command -v brew &>/dev/null; then PKG="brew"; fi
            ;;
        *)
            err "Unsupported OS: $OS"
            exit 1
            ;;
    esac
}

# ── Package lists per distro ────────────────────────────────────────────────
# Core: minimum to do a dev build (Linux native)
pkgs_core_debian="build-essential cmake git pkg-config
    libgl1-mesa-dev libx11-dev libxcursor-dev libxrandr-dev
    libxinerama-dev libxi-dev libxkbcommon-dev libwayland-dev
    libsodium-dev libcurl4-openssl-dev
    autoconf automake libtool wget python3 xxd"

pkgs_core_fedora="gcc gcc-c++ cmake git pkg-config
    mesa-libGL-devel libX11-devel libXcursor-devel libXrandr-devel
    libXinerama-devel libXi-devel libxkbcommon-devel wayland-devel
    libsodium-devel libcurl-devel
    autoconf automake libtool wget python3 vim-common"

pkgs_core_arch="base-devel cmake git pkg-config
    mesa libx11 libxcursor libxrandr libxinerama libxi
    libxkbcommon wayland libsodium curl
    autoconf automake libtool wget python xxd"

pkgs_core_macos="bash cmake python xxd"

# Windows cross-compile (from Linux)
pkgs_win_debian="mingw-w64 zip"
pkgs_win_fedora="mingw64-gcc mingw64-gcc-c++ zip"
pkgs_win_arch="mingw-w64-gcc zip"

# macOS cross-compile helpers (osxcross is separate)
pkgs_mac_debian="genisoimage icnsutils"
pkgs_mac_fedora="genisoimage"
pkgs_mac_arch="cdrtools"

# ── Helpers ──────────────────────────────────────────────────────────────────
has_cmd() { command -v "$1" &>/dev/null; }

# Install packages for the detected distro
install_pkgs() {
    local pkgs="$1"
    local desc="$2"

    if $CHECK_ONLY; then
        warn "Would install ($desc): $pkgs"
        return
    fi

    info "Installing $desc packages..."
    case "$PKG" in
        apt)    sudo apt-get update -qq && sudo apt-get install -y $pkgs ;;
        dnf)    sudo dnf install -y $pkgs ;;
        pacman)
            # Try pacman first; fall back to AUR helper for packages not in official repos
            if ! sudo pacman -S --needed --noconfirm $pkgs 2>/dev/null; then
                if command -v yay &>/dev/null; then
                    yay -S --needed --noconfirm $pkgs
                elif command -v paru &>/dev/null; then
                    paru -S --needed --noconfirm $pkgs
                else
                    err "pacman failed and no AUR helper (yay/paru) found"
                    echo "Some packages may be in the AUR. Install yay or paru, then retry."
                    return 1
                fi
            fi
            ;;
        zypper) sudo zypper install -y $pkgs ;;
        brew)   brew install $pkgs ;;
        *)      err "No supported package manager found for $DISTRO"
                echo "Please install manually: $pkgs"
                return 1 ;;
    esac
}

# Select the right package list variable
get_pkgs() {
    local category="$1"  # core, win, mac
    local var="pkgs_${category}_${DISTRO}"
    echo "${!var:-}"
}

# ── Check individual tools ──────────────────────────────────────────────────
MISSING=0

check_tool() {
    local cmd="$1"
    local label="${2:-$1}"
    if has_cmd "$cmd"; then
        ok "$label"
    else
        miss "$label  (not found: $cmd)"
        MISSING=$((MISSING + 1))
    fi
}

check_file() {
    local path="$1"
    local label="$2"
    if [[ -f "$path" ]]; then
        ok "$label"
    else
        miss "$label  ($path)"
        MISSING=$((MISSING + 1))
    fi
}

check_dir() {
    local path="$1"
    local label="$2"
    if [[ -d "$path" ]]; then
        ok "$label"
    else
        miss "$label  ($path)"
        MISSING=$((MISSING + 1))
    fi
}

# ═════════════════════════════════════════════════════════════════════════════
#  MAIN
# ═════════════════════════════════════════════════════════════════════════════
echo -e "${BOLD}DragonX Wallet — Development Setup${NC}"
echo "═══════════════════════════════════"

detect_os
info "Detected: $OS / $DISTRO (package manager: ${PKG:-none})"

# ── 1. Core build dependencies ──────────────────────────────────────────────
header "Core Build Dependencies"

core_pkgs="$(get_pkgs core)"
if [[ -z "$core_pkgs" ]]; then
    warn "No package list for $DISTRO — check README for manual instructions"
else
    # Check if key tools are already present
    NEED_CORE=false
    has_cmd cmake && has_cmd g++ && has_cmd pkg-config && has_cmd python3 && has_cmd xxd || NEED_CORE=true

    if $NEED_CORE; then
        install_pkgs "$core_pkgs" "core build"
    else
        ok "Core tools already installed (cmake, g++, pkg-config)"
    fi
fi

check_tool cmake "cmake"
check_tool g++   "g++ (C++ compiler)"
check_tool git   "git"
check_tool make  "make"
check_tool python3 "python3 (theme expansion)"
check_tool xxd "xxd (embedded language headers)"

# ── 2. libsodium ────────────────────────────────────────────────────────────
header "libsodium"

SODIUM_OK=false
# Check system libsodium
if pkg-config --exists libsodium 2>/dev/null; then
    ok "libsodium (system, $(pkg-config --modversion libsodium))"
    SODIUM_OK=true
elif [[ -f "$PROJECT_DIR/libs/libsodium/lib/libsodium.a" ]]; then
    ok "libsodium (local build)"
    SODIUM_OK=true
else
    miss "libsodium not found"
    if ! $CHECK_ONLY; then
        info "Building libsodium from source..."
        "$PROJECT_DIR/scripts/fetch-libsodium.sh" && SODIUM_OK=true
    fi
fi

# ── 3. Windows cross-compile (optional) ─────────────────────────────────────
header "Windows Cross-Compile"

if $SETUP_WIN; then
    # Only touch apt / update-alternatives (which need sudo) when the toolchain is missing. If it is
    # already installed, skip them so `./setup.sh --win` can run WITHOUT sudo — important because the
    # daemon cross-compile that follows should run as the invoking user. Running the whole setup under
    # sudo leaves root-owned build artifacts under external/dragonx, which then break `make clean` on
    # a later non-sudo build (stale objects get relinked -> the mingw link failure recurs).
    if has_cmd x86_64-w64-mingw32-g++-posix || has_cmd x86_64-w64-mingw32-g++; then
        ok "Windows cross-compile toolchain already present — skipping apt install"
    else
        win_pkgs="$(get_pkgs win)"
        if [[ -n "$win_pkgs" ]]; then
            install_pkgs "$win_pkgs" "Windows cross-compile"
        fi

        # Set posix thread model if available
        if has_cmd update-alternatives && [[ "$PKG" == "apt" ]]; then
            if ! $CHECK_ONLY; then
                sudo update-alternatives --set x86_64-w64-mingw32-gcc \
                    /usr/bin/x86_64-w64-mingw32-gcc-posix 2>/dev/null || true
                sudo update-alternatives --set x86_64-w64-mingw32-g++ \
                    /usr/bin/x86_64-w64-mingw32-g++-posix 2>/dev/null || true
            fi
        fi
    fi

    # Fetch libsodium for Windows
    if [[ ! -f "$PROJECT_DIR/libs/libsodium-win/lib/libsodium.a" ]]; then
        if ! $CHECK_ONLY; then
            info "Building libsodium for Windows target..."
            "$PROJECT_DIR/scripts/fetch-libsodium.sh" --win
        else
            miss "libsodium-win (not built yet)"
        fi
    else
        ok "libsodium-win"
    fi
fi

if has_cmd x86_64-w64-mingw32-g++-posix || has_cmd x86_64-w64-mingw32-g++; then
    ok "mingw-w64 ($(x86_64-w64-mingw32-g++-posix --version 2>/dev/null | head -1 || x86_64-w64-mingw32-g++ --version 2>/dev/null | head -1))"
else
    if $SETUP_WIN; then
        miss "mingw-w64"
    else
        skip "mingw-w64 (use --win to install)"
    fi
fi

# ── 4. macOS cross-compile (optional) ───────────────────────────────────────
header "macOS Cross-Compile"

if $SETUP_MAC; then
    mac_pkgs="$(get_pkgs mac)"
    if [[ -n "$mac_pkgs" ]]; then
        install_pkgs "$mac_pkgs" "macOS cross-compile helpers"
    fi

    # Fetch libsodium for macOS
    if [[ ! -f "$PROJECT_DIR/libs/libsodium-mac/lib/libsodium.a" ]]; then
        if ! $CHECK_ONLY; then
            # Requires osxcross — skip gracefully if not available
            if [[ -d "$PROJECT_DIR/external/osxcross/target" ]] || [[ -d "${OSXCROSS:-}/target" ]]; then
                info "Building libsodium for macOS target..."
                "$PROJECT_DIR/scripts/fetch-libsodium.sh" --mac || warn "libsodium-mac build failed"
            else
                skip "libsodium-mac (requires osxcross — see README)"
            fi
        else
            miss "libsodium-mac (not built yet)"
        fi
    else
        ok "libsodium-mac"
    fi
fi

if [[ -d "$PROJECT_DIR/external/osxcross/target" ]] || [[ -d "${OSXCROSS:-}/target" ]]; then
    ok "osxcross"
else
    if $SETUP_MAC; then
        miss "osxcross (must be set up manually — see README)"
    else
        skip "osxcross (use --mac to set up macOS deps)"
    fi
fi

# ── 5. Sapling parameters ───────────────────────────────────────────────────
header "Sapling Parameters"

SAPLING_DIR=""
for d in "$HOME/.zcash-params" "$HOME/.hush-params"; do
    if [[ -f "$d/sapling-spend.params" && -f "$d/sapling-output.params" ]]; then
        SAPLING_DIR="$d"
        break
    fi
done

# Also check project-local locations
if [[ -z "$SAPLING_DIR" ]]; then
    for d in "$PROJECT_DIR/prebuilt-binaries/dragonxd-linux" "$PROJECT_DIR/prebuilt-binaries/dragonxd-win"; do
        if [[ -f "$d/sapling-spend.params" && -f "$d/sapling-output.params" ]]; then
            SAPLING_DIR="$d"
            break
        fi
    done
fi

if [[ -n "$SAPLING_DIR" ]]; then
    ok "sapling-spend.params  ($(du -h "$SAPLING_DIR/sapling-spend.params" | cut -f1))"
    ok "sapling-output.params ($(du -h "$SAPLING_DIR/sapling-output.params" | cut -f1))"
elif $SETUP_SAPLING; then
    if ! $CHECK_ONLY; then
        info "Downloading Sapling parameters (~51 MB)..."
        PARAMS_DIR="$HOME/.zcash-params"
        mkdir -p "$PARAMS_DIR"

        SPEND_URL="https://z.cash/downloads/sapling-spend.params"
        OUTPUT_URL="https://z.cash/downloads/sapling-output.params"
        # Consensus-critical MPC parameters with fixed, well-known SHA-256 (identical across every
        # Zcash-family node; also pinned in scripts/build-lite-backend-artifact.sh). z.cash is
        # plain HTTPS with no signature, so verify the digest and refuse a tampered/corrupt file.
        SPEND_SHA256="8e48ffd23abb3a5fd9c5589204f32d9c31285a04b78096ba40a79b75677efc13"
        OUTPUT_SHA256="2f0ebbcbb9bb0bcffe95a397e7eba89c29eb4dde6191c339db88570e3f3fb0e4"

        if curl -fSL -o "$PARAMS_DIR/sapling-spend.params" "$SPEND_URL" \
           && echo "${SPEND_SHA256}  $PARAMS_DIR/sapling-spend.params" | sha256sum -c --status; then
            ok "Downloaded + verified sapling-spend.params"
        else
            rm -f "$PARAMS_DIR/sapling-spend.params"
            err "sapling-spend.params download or SHA-256 verification failed — not installed"
        fi
        if curl -fSL -o "$PARAMS_DIR/sapling-output.params" "$OUTPUT_URL" \
           && echo "${OUTPUT_SHA256}  $PARAMS_DIR/sapling-output.params" | sha256sum -c --status; then
            ok "Downloaded + verified sapling-output.params"
        else
            rm -f "$PARAMS_DIR/sapling-output.params"
            err "sapling-output.params download or SHA-256 verification failed — not installed"
        fi
    fi
else
    skip "Sapling params not found (use --sapling to download, or they'll be extracted at runtime from embedded builds)"
fi

# ── 6. DragonX daemon ────────────────────────────────────────────────────────
header "DragonX Daemon"

DRAGONX_SRC="$PROJECT_DIR/external/dragonx"
DRAGONXD_LINUX="$PROJECT_DIR/prebuilt-binaries/dragonxd-linux"
DRAGONXD_WIN="$PROJECT_DIR/prebuilt-binaries/dragonxd-win"
DRAGONXD_MAC="$PROJECT_DIR/prebuilt-binaries/dragonxd-mac"

DAEMON_BINS="dragonxd dragonx-cli dragonx-tx hushd hush-arrakis-chain hush-cli hush-tx"
DAEMON_DATA="asmap.dat sapling-spend.params sapling-output.params"

# Helper: clone / update dragonx source
clone_dragonx_if_needed() {
    if [[ ! -d "$DRAGONX_SRC" ]]; then
        info "Cloning dragonx..."
        git clone https://git.dragonx.is/DragonX/dragonx.git "$DRAGONX_SRC"
    else
        ok "dragonx source already present"
        info "Switching to dragonx branch and pulling latest..."
        (cd "$DRAGONX_SRC" && git checkout dragonx 2>/dev/null && git pull --ff-only 2>/dev/null || true)
    fi
}

# Helper: copy data files (asmap, sapling params) into a destination dir
copy_daemon_data() {
    local dest="$1"
    for p in "$DRAGONX_SRC/asmap.dat" "$DRAGONX_SRC/contrib/asmap/asmap.dat"; do
        if [[ -f "$p" ]]; then
            cp "$p" "$dest/asmap.dat"
            ok "  Installed asmap.dat"
            break
        fi
    done
    for p in sapling-spend.params sapling-output.params; do
        if [[ -f "$DRAGONX_SRC/$p" ]]; then
            cp "$DRAGONX_SRC/$p" "$dest/"
            ok "  Installed $p"
        fi
    done
}

# ── Stale-daemon guard ───────────────────────────────────────────────────────
# A prebuilt daemon binary is only rebuilt on its platform's flag (--win/--mac),
# and build.sh merely BUNDLES whatever binary already exists — so a daemon left
# over from an old source revision silently ships in the wallet (e.g. the Network
# tab once reported v1.0.1 while the source was v1.0.2). These helpers compare the
# version baked into a prebuilt binary against the dragonx source and flag drift.
STALE_DAEMON=0

# MAJOR.MINOR.REVISION from the checked-out dragonx source (empty if unavailable).
dragonx_source_version() {
    local hdr="$DRAGONX_SRC/src/clientversion.h"
    [[ -f "$hdr" ]] || return 1
    local maj min rev
    maj=$(awk '/#define[ \t]+CLIENT_VERSION_MAJOR/{print $3; exit}' "$hdr")
    min=$(awk '/#define[ \t]+CLIENT_VERSION_MINOR/{print $3; exit}' "$hdr")
    rev=$(awk '/#define[ \t]+CLIENT_VERSION_REVISION/{print $3; exit}' "$hdr")
    [[ -n "$maj" && -n "$min" && -n "$rev" ]] || return 1
    printf '%s.%s.%s' "$maj" "$min" "$rev"
}

# vX.Y.Z baked into a built daemon binary (the daemon embeds "vX.Y.Z-<githash>").
# Uses grep -a so no `strings`/binutils dependency is required.
dragonx_binary_version() {
    local bin="$1"
    [[ -f "$bin" ]] || return 1
    LC_ALL=C grep -aoE 'v[0-9]+\.[0-9]+\.[0-9]+-[0-9a-f]{6,}' "$bin" 2>/dev/null \
        | head -1 | sed -E 's/^v([0-9]+\.[0-9]+\.[0-9]+).*/\1/'
}

# Compare a prebuilt daemon against the source; warn (and set STALE_DAEMON) on drift.
#   $1 = label, $2 = binary path, $3 = rebuild flag(s) (e.g. "--win", "" for Linux)
daemon_version_guard() {
    local label="$1" bin="$2" rebuild_hint="$3"
    [[ -f "$bin" ]] || return 0
    local src bv
    src=$(dragonx_source_version) || return 0       # no source checked out → can't compare
    bv=$(dragonx_binary_version "$bin")
    [[ -n "$bv" ]] || return 0                       # couldn't read the binary's version
    if [[ "$bv" == "$src" ]]; then
        ok "  $label daemon is v$bv (matches dragonx source)"
    else
        warn "  $label daemon is v$bv but dragonx source is v$src — STALE"
        warn "    rebuild so the wallet ships the current daemon:  ./setup.sh${rebuild_hint:+ $rebuild_hint}"
        STALE_DAEMON=1
    fi
}

# ── Linux daemon ─────────────────────────────────────────────────────────────

# Skip Linux daemon build if only cross-compile targets were requested
# and we already have Linux binaries (avoids contaminating the build tree)
SKIP_LINUX_DAEMON=false
if ($SETUP_WIN || $SETUP_MAC) && [[ -f "$DRAGONXD_LINUX/dragonxd" || -f "$DRAGONXD_LINUX/hushd" ]]; then
    SKIP_LINUX_DAEMON=true
fi

# Clean previous prebuilt daemon binaries so we always rebuild
if ! $CHECK_ONLY && ! $SKIP_LINUX_DAEMON; then
    for f in $DAEMON_BINS $DAEMON_DATA; do
        rm -f "$DRAGONXD_LINUX/$f" 2>/dev/null || true
    done
fi

if $CHECK_ONLY; then
    if [[ -f "$DRAGONXD_LINUX/dragonxd" ]] || [[ -f "$DRAGONXD_LINUX/hushd" ]]; then
        ok "dragonxd daemon (Linux) present"
        daemon_version_guard "Linux" "$DRAGONXD_LINUX/dragonxd" ""
    else
        miss "dragonxd daemon (Linux) not built"
    fi
elif $SKIP_LINUX_DAEMON; then
    skip "dragonxd (Linux) — skipped, binaries already present (cross-compile only)"
    daemon_version_guard "Linux" "$DRAGONXD_LINUX/dragonxd" ""
else
    clone_dragonx_if_needed

    info "Building dragonx daemon for Linux (this may take a while)..."
    (
        cd "$DRAGONX_SRC"
        bash build.sh -j"$NPROC"
    )

    # Copy binaries to prebuilt-binaries
    mkdir -p "$DRAGONXD_LINUX"
    local_found=0
    for f in dragonxd dragonx-cli dragonx-tx hushd hush-arrakis-chain hush-cli hush-tx; do
        if [[ -f "$DRAGONX_SRC/src/$f" ]]; then
            cp "$DRAGONX_SRC/src/$f" "$DRAGONXD_LINUX/"
            chmod +x "$DRAGONXD_LINUX/$f"
            ok "  Installed $f"
            local_found=1
        fi
    done
    copy_daemon_data "$DRAGONXD_LINUX"

    if [[ $local_found -eq 0 ]]; then
        err "DragonX daemon (Linux) build failed — no binaries found"
        MISSING=$((MISSING + 1))
    else
        ok "DragonX daemon built and installed to prebuilt-binaries/dragonxd-linux/"
    fi
fi

# ── Windows daemon (cross-compile, only with --win or --all) ─────────────────

if ! $SETUP_WIN; then
    skip "dragonxd (Windows) — use --win to cross-compile"
    daemon_version_guard "Windows" "$DRAGONXD_WIN/dragonxd.exe" "--win"
elif $CHECK_ONLY; then
    if [[ -f "$DRAGONXD_WIN/dragonxd.exe" ]] || [[ -f "$DRAGONXD_WIN/hushd.exe" ]]; then
        ok "dragonxd daemon (Windows) present"
        daemon_version_guard "Windows" "$DRAGONXD_WIN/dragonxd.exe" "--win"
    else
        miss "dragonxd daemon (Windows) not built"
    fi
else
    clone_dragonx_if_needed

    # Clean previous Windows prebuilt binaries
    if ! $CHECK_ONLY; then
        rm -f "$DRAGONXD_WIN"/*.exe "$DRAGONXD_WIN"/*.bat 2>/dev/null || true
        for f in $DAEMON_DATA; do rm -f "$DRAGONXD_WIN/$f" 2>/dev/null || true; done
    fi

    info "Building dragonx daemon for Windows (cross-compile, this may take a long time)..."
    (
        cd "$DRAGONX_SRC"
        bash build.sh --win-release -j"$NPROC"
    )

    # Copy binaries from release directory
    mkdir -p "$DRAGONXD_WIN"
    local_found=0
    # Find the release subdirectory (e.g. release/dragonx-1.0.0-win64/)
    WIN_RELEASE_DIR=$(find "$DRAGONX_SRC/release" -maxdepth 1 -type d -name '*win64*' 2>/dev/null | head -1)
    for f in dragonxd.exe dragonx-cli.exe dragonx-tx.exe; do
        if [[ -n "$WIN_RELEASE_DIR" ]] && [[ -f "$WIN_RELEASE_DIR/$f" ]]; then
            cp "$WIN_RELEASE_DIR/$f" "$DRAGONXD_WIN/"
            ok "  Installed $f"
            local_found=1
        elif [[ -f "$DRAGONX_SRC/src/$f" ]]; then
            cp "$DRAGONX_SRC/src/$f" "$DRAGONXD_WIN/"
            ok "  Installed $f (from src/)"
            local_found=1
        fi
    done
    # .bat launchers
    for f in dragonxd.bat dragonx-cli.bat bootstrap-dragonx.bat; do
        if [[ -n "$WIN_RELEASE_DIR" ]] && [[ -f "$WIN_RELEASE_DIR/$f" ]]; then
            cp "$WIN_RELEASE_DIR/$f" "$DRAGONXD_WIN/"
            ok "  Installed $f"
        fi
    done
    copy_daemon_data "$DRAGONXD_WIN"

    if [[ $local_found -eq 0 ]]; then
        err "DragonX daemon (Windows) build failed — no binaries found"
        MISSING=$((MISSING + 1))
    else
        ok "DragonX daemon (Windows) built and installed to prebuilt-binaries/dragonxd-win/"
    fi
fi

# ── macOS daemon (only with --mac or --all) ──────────────────────────────────

if ! $SETUP_MAC; then
    skip "dragonxd (macOS) — use --mac to cross-compile"
    daemon_version_guard "macOS" "$DRAGONXD_MAC/dragonxd" "--mac"
elif $CHECK_ONLY; then
    if [[ -f "$DRAGONXD_MAC/dragonxd" ]] || [[ -f "$DRAGONXD_MAC/hushd" ]]; then
        ok "dragonxd daemon (macOS) present"
        daemon_version_guard "macOS" "$DRAGONXD_MAC/dragonxd" "--mac"
    else
        miss "dragonxd daemon (macOS) not built"
    fi
else
    clone_dragonx_if_needed

    # Clean previous macOS prebuilt binaries
    if ! $CHECK_ONLY; then
        for f in $DAEMON_BINS $DAEMON_DATA; do
            rm -f "$DRAGONXD_MAC/$f" 2>/dev/null || true
        done
    fi

    # macOS build requires either native macOS or osxcross
    if [[ "$OSTYPE" == "darwin"* ]]; then
        info "Building dragonx daemon for macOS (native)..."
        (
            cd "$DRAGONX_SRC"
            bash build.sh -j"$NPROC"
        )
    else
        info "Building dragonx daemon for macOS (requires osxcross)..."
        OSXCROSS=""
        for d in "$PROJECT_DIR/external/osxcross" "$HOME/osxcross" "/opt/osxcross"; do
            if [[ -d "$d/target/bin" ]]; then
                OSXCROSS="$d"
                break
            fi
        done
        if [[ -z "$OSXCROSS" ]]; then
            warn "osxcross not found — skipping macOS daemon build"
            warn "Install osxcross to external/osxcross to enable macOS cross-compilation"
        else
            info "Using osxcross at $OSXCROSS"
            (
                cd "$DRAGONX_SRC"
                export PATH="$OSXCROSS/target/bin:$PATH"
                bash util/build-mac-cross.sh 2>/dev/null || bash util/build-mac.sh
            )
        fi
    fi

    # Copy binaries
    mkdir -p "$DRAGONXD_MAC"
    local_found=0
    for f in dragonxd dragonx-cli dragonx-tx hushd hush-arrakis-chain hush-cli hush-tx; do
        if [[ -f "$DRAGONX_SRC/src/$f" ]]; then
            cp "$DRAGONX_SRC/src/$f" "$DRAGONXD_MAC/"
            chmod +x "$DRAGONXD_MAC/$f"
            ok "  Installed $f"
            local_found=1
        fi
    done
    copy_daemon_data "$DRAGONXD_MAC"

    if [[ $local_found -eq 0 ]]; then
        warn "DragonX daemon (macOS) — no binaries found (osxcross may be missing)"
    else
        ok "DragonX daemon (macOS) built and installed to prebuilt-binaries/dragonxd-mac/"
    fi
fi

# Prominent reminder if any prebuilt daemon drifted from the source — these are bundled verbatim
# by build.sh, so a stale binary ships in the wallet (and shows an old version in the Network tab).
if [[ "$STALE_DAEMON" -eq 1 ]]; then
    warn "One or more prebuilt daemons are OLDER than the dragonx source (see above)."
    warn "build.sh bundles them as-is, so rebuild the stale platform(s) before releasing:"
    warn "  Linux: ./setup.sh   ·   Windows: ./setup.sh --win   ·   macOS: ./setup.sh --mac"
fi

# ── 7. drg-xmrig (mining binary) ────────────────────────────────────────────
header "drg-xmrig Mining Binary"

XMRIG_SRC="$PROJECT_DIR/external/drg-xmrig"
# Output dir bundled by build.sh (Linux zip, AppImage, Windows embed, mac .app)
# and scripts/legacy/build-windows.sh — keep this path in sync with those.
XMRIG_PREBUILT="$PROJECT_DIR/prebuilt-binaries/drg-xmrig"

# Clean previous prebuilt xmrig binaries so we always rebuild
# Only clean the binary for the platform(s) we are actually building,
# otherwise a plain ./setup.sh deletes xmrig.exe without rebuilding it.
if ! $CHECK_ONLY; then
    rm -f "$XMRIG_PREBUILT/xmrig" 2>/dev/null || true
    if $SETUP_WIN; then
        rm -f "$XMRIG_PREBUILT/xmrig.exe" 2>/dev/null || true
    fi
fi

# Helper: clone drg-xmrig if not present
clone_xmrig_if_needed() {
    if [[ ! -d "$XMRIG_SRC" ]]; then
        info "Cloning drg-xmrig..."
        git clone https://git.dragonx.is/DragonX/drg-xmrig.git "$XMRIG_SRC"
    else
        ok "drg-xmrig source already present"
        info "Pulling latest drg-xmrig..."
        (cd "$XMRIG_SRC" && git pull --ff-only 2>/dev/null || true)
    fi
}

# ── Linux xmrig ─────────────────────────────────────────────────────────────
XMRIG_LINUX="$XMRIG_PREBUILT/xmrig"

if $CHECK_ONLY; then
    if [[ -f "$XMRIG_LINUX" ]]; then
        ok "xmrig (Linux) ($(du -h "$XMRIG_LINUX" | cut -f1))"
    else
        miss "xmrig (Linux) not built (run setup without --check to build)"
    fi
else
    clone_xmrig_if_needed

    # Clean previous build
    rm -rf "$XMRIG_SRC/build"

    # Build dependencies (libuv, hwloc, openssl)
    info "Building drg-xmrig dependencies (libuv, hwloc, openssl)..."
    (
        cd "$XMRIG_SRC/scripts"
        sh build_deps.sh
    )
    ok "drg-xmrig dependencies built"

    # Build xmrig
    info "Building drg-xmrig (Linux)..."
    mkdir -p "$XMRIG_SRC/build"
    (
        cd "$XMRIG_SRC/build"
        cmake .. \
            -DCMAKE_BUILD_TYPE=Release \
            -DWITH_OPENCL=OFF \
            -DWITH_CUDA=OFF \
            -DWITH_HWLOC=ON \
            -DCMAKE_PREFIX_PATH="$XMRIG_SRC/scripts/deps"
        make -j"$NPROC"
    )

    # Copy binary to prebuilt-binaries
    mkdir -p "$XMRIG_PREBUILT"
    if [[ -f "$XMRIG_SRC/build/xmrig" ]]; then
        cp "$XMRIG_SRC/build/xmrig" "$XMRIG_LINUX"
        ok "xmrig (Linux) built and installed to prebuilt-binaries/drg-xmrig/"
    else
        err "xmrig (Linux) build failed — binary not found"
        MISSING=$((MISSING + 1))
    fi
fi

# ── Windows xmrig (cross-compile, only with --win or --all) ─────────────────
XMRIG_WIN="$XMRIG_PREBUILT/xmrig.exe"

if ! $SETUP_WIN; then
    skip "xmrig.exe (Windows) — use --win to cross-compile"
elif $CHECK_ONLY; then
    if [[ -f "$XMRIG_WIN" ]]; then
        ok "xmrig.exe (Windows) ($(du -h "$XMRIG_WIN" | cut -f1))"
    else
        miss "xmrig.exe (Windows) not built (run setup --win without --check to build)"
    fi
else
    clone_xmrig_if_needed

    # Clean previous Windows build
    rm -rf "$XMRIG_SRC/build-windows"

    info "Building drg-xmrig (Windows cross-compile)..."
    (
        cd "$XMRIG_SRC/scripts"
        bash build_windows.sh
    )

    # Copy binary to prebuilt-binaries
    mkdir -p "$XMRIG_PREBUILT"
    if [[ -f "$XMRIG_SRC/build-windows/xmrig.exe" ]]; then
        cp "$XMRIG_SRC/build-windows/xmrig.exe" "$XMRIG_WIN"
        ok "xmrig.exe (Windows) built and installed to prebuilt-binaries/drg-xmrig/"
    else
        err "xmrig.exe (Windows) build failed — binary not found"
        MISSING=$((MISSING + 1))
    fi
fi

# ── 8. Binary directories ───────────────────────────────────────────────────
header "Binary Directories"

for platform in dragonxd-linux dragonxd-win dragonxd-mac drg-xmrig; do
    dir="$PROJECT_DIR/prebuilt-binaries/$platform"
    if [[ -d "$dir" ]]; then
        # Count actual files (not .gitkeep)
        count=$(find "$dir" -maxdepth 1 -type f ! -name '.gitkeep' | wc -l)
        if [[ $count -gt 0 ]]; then
            ok "prebuilt-binaries/$platform/ ($count files)"
        else
            skip "prebuilt-binaries/$platform/ (empty — place binaries here)"
        fi
    else
        if ! $CHECK_ONLY; then
            mkdir -p "$dir"
            touch "$dir/.gitkeep"
            ok "Created prebuilt-binaries/$platform/"
        else
            miss "prebuilt-binaries/$platform/"
        fi
    fi
done

# ── Summary ──────────────────────────────────────────────────────────────────
echo ""
echo "═══════════════════════════════════════════"
if [[ $MISSING -eq 0 ]]; then
    echo -e "${GREEN}${BOLD}  Setup complete — ready to build!${NC}"
    echo ""
    echo "  Quick start:"
    echo "    ./build.sh                  # Dev build"
    echo "    ./build.sh --linux-release  # Linux release + AppImage"
    echo "    ./build.sh --win-release    # Windows cross-compile"
else
    echo -e "${YELLOW}${BOLD}  $MISSING item(s) still need attention${NC}"
    if $CHECK_ONLY; then
        echo ""
        echo "  Run without --check to install automatically:"
        echo "    ./scripts/setup.sh"
        echo "    ./scripts/setup.sh --all    # Include cross-compile + Sapling"
    fi
fi
echo "═══════════════════════════════════════════"
