#!/usr/bin/env node
const crypto = require('crypto')

function b64urlDecode(s) {
  s = String(s || '')
  s = s.replace(/-/g, '+').replace(/_/g, '/')
  while (s.length % 4) s += '='
  return Buffer.from(s, 'base64').toString('utf8')
}

function b64urlEncode(buf) {
  return buf.toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_')
}

function verifyHS256(token, secret) {
  const parts = token.split('.')
  if (parts.length !== 3) return { ok: false, reason: 'bad token format' }
  const [h64, p64, s64] = parts
  const signingInput = `${h64}.${p64}`
  const expected = b64urlEncode(crypto.createHmac('sha256', secret).update(signingInput).digest())
  return { ok: expected === s64, expected, actual: s64 }
}

function usage() {
  console.log('Usage: node server/verify_supa_token.js <token> [secret]')
  console.log('Or set env vars: TOKEN and SECRET and run without args')
}

const token = process.argv[2] || process.env.TOKEN
const secret = process.argv[3] || process.env.SECRET || process.env.JWT_SECRET || process.env.SERVICE_ROLE_KEY || process.env.SUPA_KEY

if (!token) {
  usage()
  process.exit(2)
}

if (!secret) {
  console.error('No secret provided. Pass as second arg or set SECRET/JWT_SECRET/SERVICE_ROLE_KEY env var')
  process.exit(2)
}

try {
  const parts = token.split('.')
  const header = JSON.parse(b64urlDecode(parts[0]))
  const payload = JSON.parse(b64urlDecode(parts[1]))

  console.log('Header:')
  console.log(JSON.stringify(header, null, 2))
  console.log('Payload:')
  console.log(JSON.stringify(payload, null, 2))

  if ((header.alg || '').toUpperCase() !== 'HS256') {
    console.warn('Warning: token alg is not HS256; this verifier only checks HS256 signatures')
  }

  const res = verifyHS256(token, secret)
  if (res.ok) {
    console.log('\nSignature: VALID (HMAC-SHA256)')
  } else {
    console.log('\nSignature: INVALID')
    console.log('expected:', res.expected)
    console.log('actual  :', res.actual)
  }
} catch (e) {
  console.error('verify error', e && e.message ? e.message : e)
  process.exit(1)
}
