import test from 'node:test'
import assert from 'node:assert/strict'

import {
  buildCallbackSign,
  buildClientSign,
  createClientSignHeaders,
  verifyCallbackSign,
} from './sign.js'

// 黄金向量与 affiliate_dash 线上实现（BuildOpenV1Sign / BuildCallbackSign）同源：
// 请求 content 固定顺序 app_key/body_sha256/method/nonce/path/timestamp（恰为 ASCII 字典序），
// 回调 content 为 body_sha256=<sha256(body)>&timestamp=<ts>，均为 HMAC-SHA256 小写 hex。

test('buildClientSign matches golden vector (app_key 参数名, body 先 sha256)', () => {
  const sign = buildClientSign({
    appKey: 'ak_test_app_key_123456',
    appSecret: 'sk_test_secret_789012',
    method: 'GET',
    path: '/api/client/v1/products',
    body: '',
    timestamp: '1783394218',
    nonce: '0123456789abcdef0123456789abcdef',
  })

  assert.equal(sign, 'af6d58a4db6863b65181949696dee5c4a44fb7e5e10631044942e83f867bb855')
})

test('buildClientSign is deterministic and normalizes method case', () => {
  const base = {
    appKey: 'ak_x',
    appSecret: 'sk_x',
    path: '/p',
    body: '',
    timestamp: '1783394218',
    nonce: 'n',
  }
  const lower = buildClientSign({ ...base, method: 'get' })
  const upper = buildClientSign({ ...base, method: 'GET' })

  assert.equal(lower, upper)
  assert.equal(lower, buildClientSign({ ...base, method: 'GET' }))
})

test('createClientSignHeaders returns all four headers with consistent sign', () => {
  const headers = createClientSignHeaders({
    appKey: 'ak_test_app_key_123456',
    appSecret: 'sk_test_secret_789012',
    method: 'POST',
    path: '/api/client/v1/orders',
    body: '{"sku":"x"}',
    timestamp: '1783394218',
    nonce: 'fixed-nonce-001',
  })

  assert.equal(headers['X-App-Key'], 'ak_test_app_key_123456')
  assert.equal(headers['X-Timestamp'], '1783394218')
  assert.equal(headers['X-Nonce'], 'fixed-nonce-001')
  assert.equal(
    headers['X-Sign'],
    buildClientSign({
      appKey: 'ak_test_app_key_123456',
      appSecret: 'sk_test_secret_789012',
      method: 'POST',
      path: '/api/client/v1/orders',
      body: '{"sku":"x"}',
      timestamp: '1783394218',
      nonce: 'fixed-nonce-001',
    }),
  )
})

test('buildCallbackSign matches golden vector', () => {
  const sign = buildCallbackSign({
    callbackSecret: 'cb_test_secret_abc',
    rawBody: '{"event":"order.shipping.updated"}',
    timestamp: '1783394218',
  })

  assert.equal(sign, '96fcd83043c59f5b1c67d5eba2e6c774d53bf371607e0f7f866d6d7b8d5096ea')
})

test('verifyCallbackSign accepts valid sign and rejects tampering', () => {
  const callbackSecret = 'cb_test_secret_abc'
  const rawBody = '{"event":"order.shipping.updated"}'
  const timestamp = '1783394218'
  const sign = buildCallbackSign({ callbackSecret, rawBody, timestamp })

  assert.equal(verifyCallbackSign({ callbackSecret, rawBody, timestamp, sign }), true)
  assert.equal(
    verifyCallbackSign({
      callbackSecret,
      rawBody: '{"event":"order.created"}',
      timestamp,
      sign,
    }),
    false,
    '篡改 body 必须拒绝',
  )
  assert.equal(
    verifyCallbackSign({ callbackSecret, rawBody, timestamp: '1783394219', sign }),
    false,
    '篡改 timestamp 必须拒绝',
  )
  assert.equal(
    verifyCallbackSign({ callbackSecret: 'cb_wrong', rawBody, timestamp, sign }),
    false,
    '错误 secret 必须拒绝',
  )
  assert.equal(
    verifyCallbackSign({ callbackSecret, rawBody, timestamp, sign: sign.toUpperCase() }),
    true,
    '大写 hex 应归一为小写后通过',
  )
})
