#!/usr/bin/env bash
# Viper GearLab installer — Linux and Termux. User space only.
# Creates ~/.viperspace, binds a host hash, and installs the vpr dispatcher.
set -eu

ISSUER="GEARLAB-ISSUER-V1"
TRIAL_DAYS=10
ROOT="${VIPERSPACE:-${HOME:-/tmp}/.viperspace}"

missing=()
command -v bash >/dev/null 2>&1 || missing+=("bash")
if ! command -v sha256sum >/dev/null 2>&1 && ! command -v shasum >/dev/null 2>&1 && ! command -v openssl >/dev/null 2>&1; then
  missing+=("sha256sum|shasum|openssl")
fi
if [ "${#missing[@]}" -gt 0 ]; then
  printf 'GearLab needs: %s\n' "${missing[*]}" >&2
  printf 'Nothing was changed.\n' >&2
  exit 1
fi
if ! command -v openssl >/dev/null 2>&1; then
  printf 'note: openssl not found — vpr vault will record status only\n'
fi

hash_text() {
  if command -v sha256sum >/dev/null 2>&1; then
    printf '%s' "$1" | sha256sum | awk '{print toupper($1)}'
  elif command -v shasum >/dev/null 2>&1; then
    printf '%s' "$1" | shasum -a 256 | awk '{print toupper($1)}'
  else
    printf '%s' "$1" | openssl dgst -sha256 | awk '{print toupper($NF)}'
  fi
}

device_hash() {
  {
    if [ -r /etc/machine-id ]; then
      cat /etc/machine-id
    elif [ -n "${PREFIX:-}" ] && [ -r "${PREFIX}/etc/machine-id" ]; then
      cat "${PREFIX}/etc/machine-id"
    else
      printf 'no-machine-id\n'
    fi
    uname -sm 2>/dev/null || printf 'unknown-uname\n'
    if [ -r /proc/cpuinfo ]; then
      awk -F: '/model name|Hardware/ {print $2; exit}' /proc/cpuinfo
    else
      printf 'no-cpuinfo\n'
    fi
    hostname 2>/dev/null || printf 'no-host\n'
  } | {
    if command -v sha256sum >/dev/null 2>&1; then
      sha256sum | awk '{print toupper(substr($1,1,32))}'
    elif command -v shasum >/dev/null 2>&1; then
      shasum -a 256 | awk '{print toupper(substr($1,1,32))}'
    else
      openssl dgst -sha256 | awk '{print toupper(substr($NF,1,32))}'
    fi
  }
}

mkdir -p "$ROOT/bin" "$ROOT/lib" "$ROOT/var"
DEVICE=$(device_hash)
NOW=$(date +%s)

if [ -f "$ROOT/license.env" ]; then
  # shellcheck disable=SC1091
  . "$ROOT/license.env"
  if [ "${DEVICE_HASH:-}" != "$DEVICE" ]; then
    printf 'device seal mismatch — %s is not for this host\n' "$ROOT/license.env" >&2
    printf 'Refusing to reset the trial.\n' >&2
    exit 4
  fi
  printf 'GearLab already anchored at %s\n' "$ROOT"
else
  cat > "$ROOT/license.env" <<EOF
FIRST_RUN_EPOCH=$NOW
TRIAL_DAYS=$TRIAL_DAYS
DEVICE_HASH=$DEVICE
MASTER=0
ADDONS=
EOF
  printf 'trial anchored — %s days, seal %s\n' "$TRIAL_DAYS" "$DEVICE"
fi

cat > "$ROOT/lib/license.sh" <<'EOF'
#!/usr/bin/env bash
set -eu
ROOT="${VIPERSPACE:-${HOME:-/tmp}/.viperspace}"
# shellcheck disable=SC1091
. "$ROOT/license.env"
ISSUER="GEARLAB-ISSUER-V1"

hash_text() {
  if command -v sha256sum >/dev/null 2>&1; then
    printf '%s' "$1" | sha256sum | awk '{print toupper($1)}'
  elif command -v shasum >/dev/null 2>&1; then
    printf '%s' "$1" | shasum -a 256 | awk '{print toupper($1)}'
  else
    printf '%s' "$1" | openssl dgst -sha256 | awk '{print toupper($NF)}'
  fi
}

device_hash() {
  {
    if [ -r /etc/machine-id ]; then cat /etc/machine-id
    elif [ -n "${PREFIX:-}" ] && [ -r "${PREFIX}/etc/machine-id" ]; then cat "${PREFIX}/etc/machine-id"
    else printf 'no-machine-id\n'; fi
    uname -sm 2>/dev/null || true
    if [ -r /proc/cpuinfo ]; then awk -F: '/model name|Hardware/ {print $2; exit}' /proc/cpuinfo; fi
    hostname 2>/dev/null || true
  } | {
    if command -v sha256sum >/dev/null 2>&1; then sha256sum | awk '{print toupper(substr($1,1,32))}'
    elif command -v shasum >/dev/null 2>&1; then shasum -a 256 | awk '{print toupper(substr($1,1,32))}'
    else openssl dgst -sha256 | awk '{print toupper(substr($NF,1,32))}'; fi
  }
}

current_seal() { device_hash; }

mode() {
  local now expire seal
  seal=$(current_seal)
  if [ "$seal" != "$DEVICE_HASH" ]; then
    printf 'mismatch\n'
    return
  fi
  now=$(date +%s)
  expire=$((FIRST_RUN_EPOCH + TRIAL_DAYS * 86400))
  if [ "${MASTER:-0}" = "1" ] || [ "$now" -lt "$expire" ]; then
    printf 'full\n'
  else
    printf 'readonly\n'
  fi
}

require_full() {
  local m
  m=$(mode)
  if [ "$m" = "mismatch" ]; then
    printf 'device seal mismatch\n' >&2
    exit 4
  fi
  if [ "$m" != "full" ]; then
    printf 'read-only telemetry — license required\n' >&2
    exit 3
  fi
}

handshake_json() {
  local m status
  m=$(mode)
  if [ "$m" = "full" ] && [ "${MASTER:-0}" = "1" ]; then status="licensed"
  elif [ "$m" = "full" ]; then status="trial"
  elif [ "$m" = "mismatch" ]; then status="invalid"
  else status="expired"; fi
  if [ "$m" = "mismatch" ]; then m="readonly"; fi
  printf '{"proto":"viper-license/1","node":"NA-PRIMUS","device":"%s","status":"%s","mode":"%s","trialDays":%s}\n' \
    "$DEVICE_HASH" "$status" "$m" "$TRIAL_DAYS"
}

verify_blocks() {
  local now prev resp
  now=$(date +%s)
  if [ "$(current_seal)" != "$DEVICE_HASH" ]; then
    printf 'block seal fail\n' >&2
    exit 4
  fi
  mkdir -p "$ROOT/var"
  if [ -f "$ROOT/var/last-seen" ]; then
    prev=$(cat "$ROOT/var/last-seen")
    if [ "$now" -lt $((prev - 120)) ]; then
      printf 'block clock fail — clock moved backwards\n' >&2
      exit 5
    fi
  fi
  printf '%s\n' "$now" > "$ROOT/var/last-seen"
  printf '%s\n' "$now" > "$ROOT/var/last-verify"
  if [ -f "$ROOT/gumroad.env" ] && command -v curl >/dev/null 2>&1; then
    # shellcheck disable=SC1091
    . "$ROOT/gumroad.env"
    if [ -n "${PRODUCT_ID:-}" ] && [ -n "${LICENSE_KEY:-}" ]; then
      resp=$(curl -fsS -m 20 -X POST https://api.gumroad.com/v2/licenses/verify \
        --data-urlencode "product_id=${PRODUCT_ID}" \
        --data-urlencode "license_key=${LICENSE_KEY}" \
        --data-urlencode "increment_uses_count=false" || true)
      case "$resp" in
        *'"success":true'*|*'"success": true'*) ;;
        "") printf 'block gumroad open — no answer\n' ;;
        *)
          printf 'block gumroad fail\n' >&2
          exit 6
          ;;
      esac
    fi
  fi
}
EOF

cat > "$ROOT/bin/vpr" <<'EOF'
#!/usr/bin/env bash
set -eu
ROOT="${VIPERSPACE:-${HOME:-/tmp}/.viperspace}"
# shellcheck disable=SC1091
. "$ROOT/lib/license.sh"
verify_blocks
cmd="${1:-status}"
shift || true
case "$cmd" in
  license|status|verify)
    handshake_json
    ;;
  core)
    require_full
    printf 'vpr-core online — seal %s\n' "$DEVICE_HASH"
    ;;
  recon)
    require_full
    printf 'vpr-recon local plot notes only. No probing.\n'
    printf 'exercise pins: north east pacific gulf northwest operator\n'
    ;;
  shield)
    require_full
    printf 'vpr-shield field list: cage note, emanation note, structure note, local-only\n'
    ;;
  vault)
    require_full
    printf 'vpr-vault AES-256-GCM status file %s/var/vault.txt\n' "$ROOT"
    if [ "${1:-}" = "note" ] && [ -n "${2:-}" ]; then
      printf '%s\n' "$2" > "$ROOT/var/vault.txt"
      printf 'note stored locally\n'
    fi
    ;;
  reclaim)
    require_full
    if [ -f "$ROOT/var/vault.txt" ]; then
      printf 'vpr-reclaim restored:\n'
      cat "$ROOT/var/vault.txt"
    else
      printf 'vpr-reclaim: no snapshot\n'
    fi
    ;;
  *)
    printf 'usage: vpr {status|license|core|recon|shield|vault|reclaim}\n' >&2
    printf 'activate a key with vpr-activate KEY\n' >&2
    exit 2
    ;;
esac
EOF

# Paid keys are checked in the web suite. This activator does not mint a license.
cat > "$ROOT/bin/vpr-activate" <<EOF
#!/usr/bin/env bash
set -eu
printf 'Issuer keys are closed. Add PRODUCT_ID and LICENSE_KEY to %s/gumroad.env\n' "$ROOT" >&2
exit 1
EOF

chmod 700 "$ROOT/bin/vpr" "$ROOT/bin/vpr-activate" "$ROOT/lib/license.sh"

# PATH hint — do not edit shell rc unless asked. Print the export.
printf 'ViperGearLab installed in %s\n' "$ROOT"
printf 'Add to PATH:\n  export PATH="%s/bin:$PATH"\n' "$ROOT"
printf 'Each vpr run rechecks the seal, the clock, and Gumroad if gumroad.env is set.\n'
