#!/usr/bin/env bash
set -uo pipefail

cd "$(dirname "$0")"

wait_to_close() {
  echo ""
  read -r -p "Press Enter to close this window..." _ || true
}

on_exit() {
  code=$?
  if [ "$code" -ne 0 ]; then
    echo ""
    printf "\033[31mSolver client exited with code %s.\033[0m\n" "$code"
  fi
  wait_to_close
}
trap on_exit EXIT

info() { printf "\033[36m%s\033[0m\n" "$1"; }
success() { printf "\033[32m%s\033[0m\n" "$1"; }
fail() {
  printf "\n\033[31mERROR: %s\033[0m\n" "$1"
  exit 1
}

show_node_install_help() {
  cat <<'EOF'

Node.js LTS is required to run this client.

macOS install options:
  1. Download and install Node.js LTS from https://nodejs.org
  2. Or, if you use Homebrew, run: brew install node

Linux install option:
  Install Node.js LTS with your distribution package manager.

After installing Node.js, close this window, open a new Terminal window, and run this client again.
EOF
}

get_env_value() {
  [ -f ".env" ] || { echo ""; return; }
  grep -E "^[[:space:]]*$1[[:space:]]*=" ".env" | tail -n 1 | cut -d= -f2- | tr -d '\r' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
}

set_env_value() {
  key="$1"
  value="$2"
  tmp="$(mktemp)"
  if [ -f ".env" ]; then
    awk -v k="$key" -v v="$value" '
      BEGIN { found = 0 }
      $0 ~ "^[[:space:]]*" k "[[:space:]]*=" { print k "=" v; found = 1; next }
      { print }
      END { if (!found) print k "=" v }
    ' ".env" > "$tmp"
  else
    printf "%s=%s\n" "$key" "$value" > "$tmp"
  fi
  mv "$tmp" ".env"
}

ensure_private_key() {
  name="$1"
  label="$2"
  current="$(get_env_value "$name")"
  if [ -n "$current" ]; then
    return
  fi
  echo ""
  info "First-time setup: paste the private key for this dedicated $label wallet."
  printf "\033[33mDo not use your main wallet.\033[0m\n"
  key=""
  while [ -z "$key" ]; do
    printf "Private key: "
    stty -echo 2>/dev/null || true
    IFS= read -r key || true
    stty echo 2>/dev/null || true
    echo ""
    key="$(printf "%s" "$key" | tr -d '\r' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
  done
  set_env_value "$name" "$key"
  success "$name saved to .env."
}

echo ""
echo "3SAT CryptoMiniSat Solver Client for Linux ARM64"
echo "================================================"
echo ""

if [ ! -f ".env" ]; then
  [ -f ".env.example" ] || fail ".env.example was not found."
  cp ".env.example" ".env" || fail "Failed to create .env from .env.example."
  info "Created .env from .env.example."
fi
ensure_private_key "SOLVER_PRIVATE_KEY" "solver"

command -v node >/dev/null 2>&1 || { show_node_install_help; fail "Node.js was not found."; }
command -v npm >/dev/null 2>&1 || { show_node_install_help; fail "npm was not found. npm is installed together with Node.js LTS."; }

[ -f "bin/cryptominisat5" ] || fail "bin/cryptominisat5 was not found."
chmod +x "bin/cryptominisat5" || true

info "Checking CryptoMiniSat..."
smoke_cnf="${TMPDIR:-/tmp}/3sat-solver-smoke.cnf"
printf "p cnf 2 2\n1 2 0\n-1 2 0\n" > "$smoke_cnf" || fail "Failed to write smoke-test CNF."
solver_output="$(./bin/cryptominisat5 --verb 0 "$smoke_cnf" 2>&1 || true)"
printf "%s\n" "$solver_output" | grep -q "SATISFIABLE" || fail "CryptoMiniSat did not return SATISFIABLE in the smoke test. Output: $solver_output"
success "CryptoMiniSat works."

if [ ! -d "node_modules" ]; then
  info "Installing Node dependencies. This runs only on first setup or after node_modules is deleted."
  npm install || fail "npm install failed."
fi

info "Building solver client..."
npm run build || fail "TypeScript build failed."

success "Starting solver. Press Ctrl+C to stop it."
echo ""
npm run start
start_code=$?
if [ "$start_code" -ne 0 ]; then
  fail "Solver client stopped with an error. Check logs/solver-client.log for details."
fi
success "Solver client stopped."

