#!/usr/bin/env bash
# Aegis mainnet node installer — one download, one command.
# Downloads the aegisd binary, creates a wallet, and runs the node
# as a background service (systemd on Linux, launchd on macOS).
#
#   curl -O https://aegisprivacycoin.com/install.sh && bash install.sh
#
set -euo pipefail

# ---- chain identity (mainnet) ----
GENESIS_TIME=1789575021
PREMINE_BENEFICIARY=0a119da86c62dbd279e8fb2c1562d0ada59425554e7b0e827840c1b300c69223c4229ce6dc20ae6a48158b99b3512a6e547001dada5de9eb4ef75208ed07df5c
MINT_AUTHORITY_PK=bf5ec0ef5a22168c8ef64699fb00e8d563290c83adb9537ca7fd83d4f852add8c433143c231bf1351ebb9d3a9f8c44b8048a9e4cd5c3fc82ff5601118f0c5a3f9d444404c09ff130a9bfb3324943f62acb786d43e0b94410481d516933e97dcc29ed1aa7a8e85c5b4d39e60779ca8c526af60e422cbee45db69b4d0dfeeb13dc49fba74a59d175c07e79615895fd30329ca02aa2f53d3270f8518018fee78ae3a5e35004a3fc956620469f2b6a40dfada7c334fac16e1261cf92d61630b34f7f7c1609e7a0dc3be806a8db13336c6ec95f37326d8b50f30dd144667b64a9e9b1580edf235e0b451681cd27e1cd6b76fc74cc7bdd79b6d5100fcc870ca22a40b635a2b15955c59d76b42b82b1052b7204a5163703e354574018d4939830fb94fc7afa25943a5d34dfa3f5dc75b0aad4cf85e0cc199e78928c4f8a497f45af2dab5fb14fc0c48f925a8bdd15b2fc2a9d4d12ef9f41673646741e883fc9a5bd9024c9c80f53e95a0cd4741f0d7fdd3bd6bc39c463d2d144d2336c0a111096d2e33aabb5b5d8bacc32373b26ff2942df1147d21aad28d6f7c0c5152be22f696df06fbb9a2130dc731b23e26d0f21a32e738591ae7382bd71c0f9736ef2ae946b6a4f59015b9f5cbece77f87388b4bfd064c832643df4b8c2e3d09e5ad9806c13ca92a3ceecbe89d13577d4de0b14fe302c0bb37816158fe2790be043aef72509218dcfc415b9acf721394e6ce2384778e2cb76924c38fc6a095f5ea54e7036234125c4dadc5d283f630180228817544302b1728d9464af026f055c51c56bc1d0e121dbd9f097b636d82c7058e7c02c2247a8fc38c3155323365f4cc6e0a4894da0cc77b8e302847e55080624c3f85d572f4e5d2e57fd2d3d9c76e561aa3196f77328169e45d2767cd42a7f7332a836fa0635481231a9e590609abeceae4039128f540950609b1e15dd7e1d92f8e3bce6c25fe6d58237b3e65a5bf423e5872006790d268f42595f2870a0a536070a13bdfc4b3798c40f3016ee51492f23cbeb6212b3406a320c53df654fe7b2a64c5c60cb03aeb1bda6c06d8c636081f5389b598abdae8fe0a06483c34dd0b44c5aea8c13cc9e59e3bdc30212eebba0b47713a442f57e07e1094a0cbd2aa4367bde5033b200bb6023a0de3f917337ef73250343a14404da6652db56e60c4140aefb48c5c971d6a90ee907ce150a6bae5acf71e83d7ffaa6add759fda3a9ebe98a80f7b703ce1fdd128bb046cead5f526704841c806bb87c768a9d059457ada977ca36c6274d8466c54879ec4e616357c524e2b2d50498408dbc67ad00f9e2230f31b6fb6dc605daa1eaae8813539062ecd50cbc731b88f913c8061f161caedde94ae33269ee56d3658f3a6d4d29fcc333c30b26d7d463264b5aeaf5f12bb5591044e8ab3c6bedca4c43981fec572133ed4be079782a1ba6817555024707e968760328f33f594dec6eb78698f23922ff0891f100a8ad97cb14a21006ea775510cfcf58cf89db39d7fbce7115c73146fb7257c10c3b43ad29e3051040e1e10e92f78d94ba7b9b459955ce732f26962939bd07bc73d1869695bf76463add62fe8b96942361eaa6ad139e995efd26507276e1e01e1b3c8359b7d975237c182dfef68eba89aab0252ba7232654f24dcee9575fe32c755abf659e9d51d285da22b20865a03a0fa45931409b61a1c87e3888ae2e2a252ccf60b45f3f368594920a62a4d6d6958e212ff3e7631299d44b0686b2966f3a46b4295ad65410927f8727c145916915084d2631ad4d5eff118bcb09dc7a15048b9346345392885a43475cf0babc805e629d0070ac208563ce2471d8188f5f466fda7bbe8c34b84775ae9c4a40a9ed3b5ad82c7f8d13bf546a24156085a12efc7d593a4035e75c64d5b37e5ed4fed361d6320aadb3671439a5172b8c00a4daacfc3c1d1d003cee2ee31dc7984ef4f9b0fbf0da12b3b617017c03def6ca10b6880639958f0580ef5a4528ae2f84b28aba9a96786b7d7e215d10e00870e9cb3fbb4a3004a802dca90876239d8f567db94ab805817bf1a75ecb32425ede763d6c487499e783f4557807f334785bee631ad2160e604c9b9739889e436a124ab6b42f1a29f84ed1706d9d794ab11f6ae50a555295cffd961572bbadb6ee5f7c1a1cda77218ee5c9b3bd30c18898a391a73adc6f8de0c9c59b0652da9eaf8ad528087f7476cfdfe22544dd7ab201c476d3852fa8e62dcec42f3031ce1c6e4af29e5615fb611ed8149918104db60c3466b5571c8943e39446233a832a06e271728c0be4efb93f6623c0a3f751943016f83884237cc8171d71b7e9786c233d1ac16abcd574c3a45dfae8a26a2b6714d4ae88d6dd3b3efd7cb6389146957b162f9661d3879a22ba006a8b7b8bdc1bb01e03fb2ca1cda63eb90b5b4f51d91f5b8825952eccf0d72b55dc03fd6a1a4df7a8705411ef7fdef1a5facd080522fa1d0d77259bce9faac6d4e6c1b3afa88ca93077ada4c1feb2a67f8f68a36707cefeb19ea43e534834a22748ebd72a96594d6799152721a8770b9b3b1c7e638377523fa622b43eb4bfa5156ca7107645b9d7dd1f3561208ace71c6a4d4e81c489d1aa048c1f579b36616e970530a8ca56f622db25811fba72606d5251b6b9fc450e7818e1a68cf0d14a255b47d84a834d733598897f469c4743501dd9d95f1b2819f2562a205deb62d33e0db9f6247f205b00feb0fe35b782a1d787d8ddfe6c608102592b69e0e8570bf
PEER=185.246.190.219:9100
BASE_URL=https://aegisprivacycoin.com

echo "==> Aegis mainnet node installer"
echo ""

# --- detect platform ---
OS=$(uname -s)
if [ "$OS" = "Linux" ]; then
    BIN_URL="$BASE_URL/aegisd"
    if [ "$(uname -m)" != "x86_64" ]; then
        echo "ERROR: this installer ships a Linux x86-64 binary; your CPU is $(uname -m)."
        echo "Build from source instead: cargo build --release -p loop-node"
        exit 1
    fi
    DATA_DIR="${AEGIS_DATA:-$HOME/.aegisd}"
elif [ "$OS" = "Darwin" ]; then
    BIN_URL="$BASE_URL/files/aegisd-macos"
    DATA_DIR="${AEGIS_DATA:-$HOME/.aegisd}"
else
    echo "ERROR: unsupported OS: $OS"
    exit 1
fi

# --- port preflight: fail loudly instead of starting a half-dead node ---
# A second node on the same machine cannot bind these ports and used to die
# silently in the background (log line only), while the operator watched the
# RPC of the OLD node and thought the new one was syncing.
port_busy() {
    if command -v lsof >/dev/null 2>&1; then
        lsof -nP -iTCP:"$1" -sTCP:LISTEN >/dev/null 2>&1
    else
        (exec 3<>/dev/tcp/127.0.0.1/"$1") >/dev/null 2>&1
    fi
}
for p in 8631 9090 9100; do
    if port_busy "$p"; then
        echo ""
        echo "ERROR: TCP port $p is already in use on this machine."
        echo "       An Aegis node (or another service) is already running here."
        echo "       Stop it first:"
        echo "         Linux:  systemctl --user stop aegisd"
        echo "         macOS:  launchctl unload ~/Library/LaunchAgents/net.aegis.node.plist"
        echo "       ...then run this installer again."
        exit 1
    fi
done

# --- install dir ---
INSTALL_DIR="$HOME/.aegis-bin"
mkdir -p "$INSTALL_DIR" "$DATA_DIR"
chmod 700 "$DATA_DIR"   # holds the wallet seed and the node password

# --- download binary (if not already present) ---
BIN="$INSTALL_DIR/aegisd"
if [ ! -x "$BIN" ]; then
    echo "==> Downloading aegisd (~7.5 MB)..."
    curl -fsSL -o "$BIN.tmp" "$BIN_URL"
    chmod +x "$BIN.tmp"
    mv "$BIN.tmp" "$BIN"
fi
echo "==> Binary: $BIN"

# Newer aegisd builds have --sync-first (do not mine before the first peer is met: a node that mines
# on top of an old snapshot ends up on a private fork) and --admin-password-file (keeps the password
# out of the process list). Older builds do not know them and would refuse to start, so only pass what
# the downloaded binary contains. The flag names are plain strings inside the binary.
SYNC_FLAG=""
PW_ARGS_KIND="value"
if grep -aq -- '--sync-first' "$BIN"; then SYNC_FLAG="--sync-first"; fi
if grep -aq -- '--admin-password-file' "$BIN"; then PW_ARGS_KIND="file"; fi

# --- wallet ---
if [ -f "$DATA_DIR/wallet.seed" ]; then
    echo "==> Wallet already exists (keeping it — your address stays the same)."
else
    echo "==> Creating your wallet..."
# --- bootstrap: start from the network's proven state (checkpoint sync) ---
if [ ! -f "$DATA_DIR/state.bin" ]; then
  echo "[aegis] fetching the network snapshot (checkpoint sync)..."
  if curl -fsSL --max-time 180 -o "$DATA_DIR/.state.tmp" "$BASE_URL/files/aegis-state.bin" \
     && curl -fsSL --max-time 30 -o "$DATA_DIR/.state.sha" "$BASE_URL/files/aegis-state.sha"; then
    GOT=$(shasum -a 256 "$DATA_DIR/.state.tmp" 2>/dev/null | cut -d" " -f1)
    [ -z "$GOT" ] && GOT=$(sha256sum "$DATA_DIR/.state.tmp" | cut -d" " -f1)
    if [ "$GOT" = "$(tr -d " \n" < "$DATA_DIR/.state.sha")" ]; then
      mv "$DATA_DIR/.state.tmp" "$DATA_DIR/state.bin"
      echo "[aegis] snapshot verified — starting at the network's state"
    else
      rm -f "$DATA_DIR/.state.tmp"; echo "[aegis] snapshot hash mismatch — starting from genesis"
    fi
  else
    rm -f "$DATA_DIR/.state.tmp"; echo "[aegis] snapshot unavailable — starting from genesis"
  fi
  rm -f "$DATA_DIR/.state.sha"
fi

    AEGIS_DATA="$DATA_DIR" "$BIN" init
fi
echo ""

# --- local wallet-UI password (generated once, stored 0600) ---
ADMIN_PASS_FILE="$DATA_DIR/admin.pass"
if [ ! -f "$ADMIN_PASS_FILE" ]; then
    ( umask 077; openssl rand -base64 18 2>/dev/null || head -c 24 /dev/urandom | base64 ) | tr -d '\n' > "$ADMIN_PASS_FILE"
fi
chmod 600 "$ADMIN_PASS_FILE"
if [ "$PW_ARGS_KIND" = "file" ]; then
    PW_ARGS="--admin-password-file $ADMIN_PASS_FILE"
else
    # old binary: the password has to go on the command line (visible to local users)
    PW_ARGS="--admin-password $(cat "$ADMIN_PASS_FILE")"
fi

# --- service setup ---
if command -v systemctl >/dev/null 2>&1 && [ "$OS" = "Linux" ]; then
    UNIT="$HOME/.config/systemd/user/aegisd.service"
    mkdir -p "$HOME/.config/systemd/user"
    cat > "$UNIT" <<EOF
[Unit]
Description=Aegis mainnet node
After=network-online.target

[Service]
ExecStart=$BIN serve --rpc 127.0.0.1:8631 --p2p 0.0.0.0:9100 --peer $PEER --mine $SYNC_FLAG --interval 60 --wallet-port 127.0.0.1:9090 $PW_ARGS
Environment=AEGIS_DATA=$DATA_DIR
Environment=AEGIS_GENESIS_TIME=$GENESIS_TIME
Environment=AEGIS_PREMINE_BENEFICIARY=$PREMINE_BENEFICIARY
Environment=AEGIS_MINT_AUTHORITY_PK=$MINT_AUTHORITY_PK
Restart=on-failure

[Install]
WantedBy=default.target
EOF
    systemctl --user daemon-reload
    systemctl --user enable --now aegisd.service >/dev/null 2>&1 || true
    echo "==> Node running as a background service (systemd, user-level)."
    echo "    Status: systemctl --user status aegisd"
    echo "    Logs:   journalctl --user -u aegisd -f"
else
    # fallback: plain background process via nohup
    nohup env AEGIS_DATA="$DATA_DIR" AEGIS_GENESIS_TIME="$GENESIS_TIME" \
        AEGIS_PREMINE_BENEFICIARY="$PREMINE_BENEFICIARY" \
        AEGIS_MINT_AUTHORITY_PK="$MINT_AUTHORITY_PK" \
        "$BIN" serve --rpc 127.0.0.1:8631 --p2p 0.0.0.0:9100 --peer "$PEER" \
        --mine $SYNC_FLAG --interval 60 --wallet-port 127.0.0.1:9090 $PW_ARGS \
        >> "$DATA_DIR/node.log" 2>&1 &
    echo "==> Node running in the background (log: $DATA_DIR/node.log)."
fi

echo ""
echo "Your node address:"
AEGIS_DATA="$DATA_DIR" "$BIN" address
echo ""
echo "What now?"
echo "  MINING IS ALREADY ON — your node mines a block every 60 seconds into"
echo "  your wallet, as soon as it has synced with the network (it skips"
echo "  mining while it is still catching up, so you can leave it running)."
echo ""
echo "  YOUR WALLET (browser, this machine only):  http://127.0.0.1:9090"
echo "     - balance, your validator + stake, UNSTAKE, and your recovery phrase"
echo "     - operator password (for stake/unstake): in $DATA_DIR/admin.pass (cat it; it is not printed here)"
echo ""
echo "  1. STAKE — become a validator (needs 1,000 AEG on your wallet):"
echo "       aegisd rpc stake 1000 --rpc 127.0.0.1:8631"
echo "  2. UNSTAKE — stop being a validator (stake returns after ~21 days):"
echo "       aegisd unstake"
echo "  3. Stop mining (if you want):  aegisd rpc setmining false --rpc 127.0.0.1:8631"
echo "  4. Track the chain: https://aegisprivacycoin.com/blocks"
echo ""
echo "Back up your wallet NOW — two things:"
echo "  1. The 24-WORD RECOVERY PHRASE printed above by 'aegisd init' — write it"
echo "     on paper and store it offline. Those words ARE your coins."
echo "     Show them again any time with:  AEGIS_DATA=$DATA_DIR aegisd backup"
echo "  2. The seed file itself: $DATA_DIR/wallet.seed (mode 0600, this user only)."
