import { timingSafeEqual } from '@platform-modules/util/crypto'

function toBase64Url(bytes: Uint8Array): string {
  let binary = ''
  for (const byte of bytes) {
    binary += String.fromCharCode(byte)
  }

  return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '')
}

export async function deriveCodeChallengeS256(codeVerifier: string): Promise<string> {
  const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier))
  return toBase64Url(new Uint8Array(digest))
}

export async function verifyCodeVerifierS256(
  codeVerifier: string,
  codeChallenge: string,
): Promise<boolean> {
  return timingSafeEqual(await deriveCodeChallengeS256(codeVerifier), codeChallenge)
}
