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

NSIGNER_BIN="${NSIGNER_BIN:-./build/nsigner}"
socket_name=""

if [[ ! -x "$NSIGNER_BIN" ]]; then
  echo "[error] nsigner binary not found or not executable at: $NSIGNER_BIN"
  echo "        Build it first with: make dev"
  exit 1
fi

while [[ $# -gt 0 ]]; do
  case "$1" in
    -n|--name|--socket-name)
      if [[ $# -lt 2 ]]; then
        echo "[error] missing value for $1"
        exit 1
      fi
      socket_name="$2"
      shift 2
      ;;
    -h|--help)
      echo "Usage: $0 [-n|--name|--socket-name <socket_name>]"
      exit 0
      ;;
    *)
      echo "[error] unknown argument: $1"
      echo "Usage: $0 [-n|--name|--socket-name <socket_name>]"
      exit 1
      ;;
  esac
done

echo "n_signer interactive smoke test"
echo "Using binary: $NSIGNER_BIN"
echo

if [[ -z "$socket_name" ]]; then
  default_socket=""
  if [[ -r /proc/net/unix ]]; then
    default_socket="$(awk '/@nsigner_/ {sub(/^@/, "", $8); print $8; exit}' /proc/net/unix || true)"
  fi

  if [[ -n "$default_socket" ]]; then
    read -r -p "Signer socket name (without @) [${default_socket}]: " socket_name
    socket_name="${socket_name:-$default_socket}"
  else
    read -r -p "Signer socket name (without @, e.g. nsigner_hairy_dog): " socket_name
  fi
fi

if [[ -z "${socket_name}" ]]; then
  echo "[error] socket name is required"
  exit 1
fi

run_request() {
  local req="$1"
  "$NSIGNER_BIN" --socket-name "$socket_name" client "$req" || true
}

extract_result_string() {
  sed -n 's/.*"result":"\([^"]*\)".*/\1/p'
}

echo
echo "[1/7] get_public_key"
req_get='{"id":"1","method":"get_public_key","params":[]}'
resp_get="$(run_request "$req_get")"
echo "request : $req_get"
echo "response: $resp_get"
pubkey="$(printf '%s' "$resp_get" | sed -n 's/.*"result":"\([0-9a-fA-F]\{64\}\)".*/\1/p')"
if [[ -n "$pubkey" ]]; then
  echo "pubkey  : $pubkey"
else
  echo "[warn] could not parse pubkey from response"
fi

echo
echo "[2/7] sign_event"
now_ts="$(date +%s)"
event_json='{"kind":1,"content":"hello from tests/test.sh","tags":[],"created_at":__TS__}'
event_json="${event_json/__TS__/${now_ts}}"
escaped_event_json="${event_json//\"/\\\"}"
req_sign="{\"id\":\"2\",\"method\":\"sign_event\",\"params\":[\"${escaped_event_json}\",{\"role\":\"main\"}]}"
resp_sign="$(run_request "$req_sign")"
echo "request : $req_sign"
echo "response: $resp_sign"
if printf '%s' "$resp_sign" | grep -q '"result"'; then
  echo "[ok] sign_event returned result"
else
  echo "[warn] sign_event did not return result"
fi

echo
echo "[3/7] sign_event with nostr_index=0"
req_sign_idx="{\"id\":\"3\",\"method\":\"sign_event\",\"params\":[\"${escaped_event_json}\",{\"nostr_index\":0}]}"
resp_sign_idx="$(run_request "$req_sign_idx")"
echo "request : $req_sign_idx"
echo "response: $resp_sign_idx"

echo
echo "[4/7] role selector error case (unknown role)"
req_bad_role='{"id":"4","method":"sign_event","params":["{}",{"role":"does_not_exist"}]}'
resp_bad_role="$(run_request "$req_bad_role")"
echo "request : $req_bad_role"
echo "response: $resp_bad_role"
if printf '%s' "$resp_bad_role" | grep -q '"message":"unknown_role"'; then
  echo "[ok] unknown role error name is unknown_role"
else
  echo "[warn] unknown role error name mismatch"
fi

echo
echo "[5/7] NIP-04 self round-trip"
if [[ -n "$pubkey" ]]; then
  req_nip04_enc="{\"id\":\"5\",\"method\":\"nip04_encrypt\",\"params\":[\"${pubkey}\",\"hello_nip04_from_test_sh\"]}"
  resp_nip04_enc="$(run_request "$req_nip04_enc")"
  echo "request : $req_nip04_enc"
  echo "response: $resp_nip04_enc"
  cipher_nip04="$(printf '%s' "$resp_nip04_enc" | extract_result_string)"
  if [[ -n "$cipher_nip04" ]]; then
    req_nip04_dec="{\"id\":\"6\",\"method\":\"nip04_decrypt\",\"params\":[\"${pubkey}\",\"${cipher_nip04}\"]}"
    resp_nip04_dec="$(run_request "$req_nip04_dec")"
    echo "request : $req_nip04_dec"
    echo "response: $resp_nip04_dec"
    if printf '%s' "$resp_nip04_dec" | grep -q '"result":"hello_nip04_from_test_sh"'; then
      echo "[ok] nip04 decrypt recovered plaintext"
    else
      echo "[warn] nip04 decrypt did not recover expected plaintext"
    fi
  else
    echo "[warn] could not parse nip04 ciphertext"
  fi
else
  echo "[warn] skipping nip04 test (missing pubkey)"
fi

echo
echo "[6/7] NIP-44 self round-trip"
if [[ -n "$pubkey" ]]; then
  req_nip44_enc="{\"id\":\"7\",\"method\":\"nip44_encrypt\",\"params\":[\"${pubkey}\",\"hello_nip44_from_test_sh\"]}"
  resp_nip44_enc="$(run_request "$req_nip44_enc")"
  echo "request : $req_nip44_enc"
  echo "response: $resp_nip44_enc"
  cipher_nip44="$(printf '%s' "$resp_nip44_enc" | extract_result_string)"
  if [[ -n "$cipher_nip44" ]]; then
    req_nip44_dec="{\"id\":\"8\",\"method\":\"nip44_decrypt\",\"params\":[\"${pubkey}\",\"${cipher_nip44}\"]}"
    resp_nip44_dec="$(run_request "$req_nip44_dec")"
    echo "request : $req_nip44_dec"
    echo "response: $resp_nip44_dec"
    if printf '%s' "$resp_nip44_dec" | grep -q '"result":"hello_nip44_from_test_sh"'; then
      echo "[ok] nip44 decrypt recovered plaintext"
    else
      echo "[warn] nip44 decrypt did not recover expected plaintext"
    fi
  else
    echo "[warn] could not parse nip44 ciphertext"
  fi
else
  echo "[warn] skipping nip44 test (missing pubkey)"
fi

echo
echo "[7/7] list currently running signers"
list_resp="$($NSIGNER_BIN list 2>&1 || true)"
echo "$list_resp"
if printf '%s' "$list_resp" | grep -q '^@nsigner'; then
  echo "[ok] signer list contains nsigner entries"
else
  echo "[warn] no @nsigner entries found"
fi

echo
echo "[extra] mnemonic startup input tests"
if [[ -x ./build/test_mnemonic_input ]]; then
  ./build/test_mnemonic_input || true
else
  echo "[warn] build/test_mnemonic_input not found (run: make test-mnemonic-input)"
fi

echo
echo "Smoke test complete."