#!/usr/bin/env bash
# ============================================================
# Timmy Bitcoin Node — One-shot bootstrap for Ubuntu 22.04 LTS
# Run as root on a fresh Digital Ocean droplet:
#   bash setup.sh
# ============================================================
set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
info()  { echo -e "${CYAN}[setup]${NC} $*"; }
ok()    { echo -e "${GREEN}[ok]${NC} $*"; }
warn()  { echo -e "${YELLOW}[warn]${NC} $*"; }
die()   { echo -e "${RED}[error]${NC} $*"; exit 1; }

[[ $EUID -ne 0 ]] && die "Run as root: sudo bash setup.sh"

# ── 0. Config ────────────────────────────────────────────────
DATA_DIR="/data"
INFRA_DIR="/opt/timmy-node"
RPC_PASS=$(openssl rand -hex 24)

info "Starting Timmy node setup..."
echo ""

# ── 1. System packages ───────────────────────────────────────
info "Updating system packages..."
apt-get update -qq
apt-get upgrade -y -qq
apt-get install -y -qq curl wget git ufw jq openssl

# ── 2. Docker ────────────────────────────────────────────────
info "Installing Docker..."
if ! command -v docker &>/dev/null; then
  curl -fsSL https://get.docker.com | sh
  systemctl enable docker
  systemctl start docker
fi
docker --version
ok "Docker ready"

# ── 3. Tailscale ─────────────────────────────────────────────
info "Installing Tailscale..."
if ! command -v tailscale &>/dev/null; then
  curl -fsSL https://tailscale.com/install.sh | sh
fi
ok "Tailscale installed — you will authenticate it after this script finishes"

# ── 4. Firewall ──────────────────────────────────────────────
info "Configuring UFW firewall..."
ufw --force reset
# Allow Tailscale
ufw allow in on tailscale0
# Bitcoin P2P
ufw allow 8333/tcp comment "Bitcoin P2P"
# Lightning P2P
ufw allow 9735/tcp comment "Lightning P2P"
# SSH via Tailscale only — but keep public SSH open until Tailscale is confirmed
# (after Tailscale auth, you can run: ufw delete allow 22)
ufw allow 22/tcp comment "SSH (disable after Tailscale is confirmed)"
ufw default deny incoming
ufw default allow outgoing
ufw --force enable
ok "Firewall configured"

# ── 5. Mount the DO block volume ─────────────────────────────
info "Setting up data volume..."
# Digital Ocean attaches block volumes at /dev/sda or /dev/disk/by-id/scsi-...
# Find the attached volume (should be the largest unmounted disk)
VOLUME_DEV=$(lsblk -rno NAME,SIZE,MOUNTPOINT | awk '$3=="" && $2~/G/ {print $1}' | grep -v "^sda$" | head -1)

if [[ -z "$VOLUME_DEV" ]]; then
  warn "Could not auto-detect a block volume. If you attached a DO Volume,"
  warn "run: lsblk   to find it, then: mkfs.ext4 /dev/<name> && mount /dev/<name> /data"
  warn "Then re-run this script or continue manually."
  mkdir -p "$DATA_DIR"
else
  VOLUME_PATH="/dev/$VOLUME_DEV"
  info "Found volume at $VOLUME_PATH"
  # Format only if not already formatted
  if ! blkid "$VOLUME_PATH" &>/dev/null; then
    info "Formatting $VOLUME_PATH with ext4..."
    mkfs.ext4 -F "$VOLUME_PATH"
  fi
  mkdir -p "$DATA_DIR"
  mount "$VOLUME_PATH" "$DATA_DIR"
  # Persist mount across reboots
  BLKID=$(blkid -s UUID -o value "$VOLUME_PATH")
  if ! grep -q "$BLKID" /etc/fstab; then
    echo "UUID=$BLKID $DATA_DIR ext4 defaults,nofail 0 2" >> /etc/fstab
  fi
  ok "Volume mounted at $DATA_DIR"
fi

# ── 6. Directory structure ───────────────────────────────────
info "Creating directory structure..."
mkdir -p \
  "$DATA_DIR/bitcoin" \
  "$DATA_DIR/lnd" \
  "$DATA_DIR/lnbits" \
  "$INFRA_DIR/configs"
ok "Directories ready"

# ── 7. Copy configs & inject RPC password ────────────────────
info "Installing configs..."
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Bitcoin config — bitcoinknots/bitcoin image uses /home/bitcoin/.bitcoin inside container
# which maps to $DATA_DIR/bitcoin on the host via the Docker volume bind
cp "$SCRIPT_DIR/configs/bitcoin.conf" "$DATA_DIR/bitcoin/bitcoin.conf"
echo "rpcpassword=$RPC_PASS" >> "$DATA_DIR/bitcoin/bitcoin.conf"

# LND config — inject rpcpass
cp "$SCRIPT_DIR/configs/lnd.conf" "$INFRA_DIR/configs/lnd.conf"
sed -i "s/# bitcoind.rpcpass is written by setup.sh at runtime/bitcoind.rpcpass=$RPC_PASS/" \
  "$INFRA_DIR/configs/lnd.conf"

# Mount lnd.conf into container via docker-compose override
cat > "$INFRA_DIR/docker-compose.override.yml" <<OVERRIDE
services:
  lnd:
    volumes:
      - lnd_data:/root/.lnd
      - $INFRA_DIR/configs/lnd.conf:/root/.lnd/lnd.conf:ro
OVERRIDE

# Copy main docker-compose and scripts
cp "$SCRIPT_DIR/docker-compose.yml" "$INFRA_DIR/docker-compose.yml"
cp "$SCRIPT_DIR/lnd-init.sh" "$INFRA_DIR/lnd-init.sh"
cp "$SCRIPT_DIR/sweep.sh" "$INFRA_DIR/sweep.sh"
cp "$SCRIPT_DIR/ops.sh" "$INFRA_DIR/ops.sh"
chmod +x "$INFRA_DIR/lnd-init.sh" "$INFRA_DIR/sweep.sh" "$INFRA_DIR/ops.sh"

ok "Configs installed"

# ── 7b. Install cron jobs ─────────────────────────────────────
info "Installing cron jobs (daily sweep + daily backup)..."
# Remove any existing Timmy cron entries before re-adding
crontab -l 2>/dev/null | grep -v "timmy-node" | crontab - || true
(crontab -l 2>/dev/null; cat <<'CRON'
# Timmy Node — auto-sweep hot wallet to cold storage (3am UTC daily)
# sweep.sh manages its own logging to /var/log/timmy-sweep.log via tee
0 3 * * * bash /opt/timmy-node/sweep.sh > /dev/null 2>&1
# Timmy Node — LND channel state backup (4am UTC daily)
0 4 * * * bash /opt/timmy-node/ops.sh backup >> /var/log/timmy-backup.log 2>&1
CRON
) | crontab -
touch /var/log/timmy-sweep.log /var/log/timmy-backup.log
ok "Cron jobs installed (sweep 3am, backup 4am UTC)"

# ── 8. Save credentials ──────────────────────────────────────
CREDS_FILE="/root/node-credentials.txt"
cat > "$CREDS_FILE" <<CREDS
# Timmy Node Credentials — keep this safe
# Generated: $(date -u)

BITCOIN_RPC_USER=satoshi
BITCOIN_RPC_PASS=$RPC_PASS
CREDS
chmod 600 "$CREDS_FILE"
ok "Credentials saved to $CREDS_FILE"

# ── 9. Start Bitcoin Core ────────────────────────────────────
info "Starting Bitcoin Core (this begins chain sync — will take days)..."
cd "$INFRA_DIR"
docker compose up -d bitcoin
ok "Bitcoin Core started"

# ── 10. Done ─────────────────────────────────────────────────
echo ""
echo -e "${GREEN}════════════════════════════════════════${NC}"
echo -e "${GREEN} Setup complete — next steps:${NC}"
echo -e "${GREEN}════════════════════════════════════════${NC}"
echo ""
echo -e "  1. ${CYAN}Authenticate Tailscale:${NC}"
echo -e "     tailscale up --ssh"
echo -e "     (copy the auth URL, open in browser, log in)"
echo ""
echo -e "  2. ${CYAN}Verify Tailscale SSH works${NC} from another device:"
echo -e "     ssh root@<node-name>  (via Tailscale MagicDNS)"
echo -e "     Then lock down public SSH:"
echo -e "     ufw delete allow 22"
echo ""
echo -e "  3. ${CYAN}Check Bitcoin sync progress:${NC}"
echo -e "     watch -n 10 'docker exec bitcoin bitcoin-cli getblockchaininfo | jq .verificationprogress'"
echo -e "     (will show 0.0 → 1.0 over several days)"
echo ""
echo -e "  4. ${CYAN}Once sync reaches ~1.0, initialize LND:${NC}"
echo -e "     bash $INFRA_DIR/lnd-init.sh"
echo ""
echo -e "  Credentials: ${YELLOW}cat $CREDS_FILE${NC}"
echo ""
