import type {HydrogenSession} from '@shopify/hydrogen'

import type {QueryParams, QueryWithoutParams} from './client'

/**
 * Create an SHA-256 hash as a hex string
 * @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string
 */
export async function sha256(message: string): Promise<string> {
  // encode as UTF-8
  const messageBuffer = await new TextEncoder().encode(message)
  // hash the message
  const hashBuffer = await crypto.subtle.digest('SHA-256', messageBuffer)
  // convert bytes to hex string
  return Array.from(new Uint8Array(hashBuffer))
    .map((b) => b.toString(16).padStart(2, '0'))
    .join('')
}

/**
 * Hash query and its parameters for use as cache key
 * NOTE: Oxygen deployment will break if the cache key is long or contains `\n`
 */
export function hashQuery(
  query: string,
  params: QueryParams | QueryWithoutParams,
): Promise<string> {
  let hash = query

  if (params) {
    hash += JSON.stringify(params)
  }

  return sha256(hash)
}

export function assertSession(session: unknown): session is HydrogenSession {
  return (
    !!session &&
    typeof session === 'object' &&
    'get' in session &&
    typeof session.get === 'function' &&
    'set' in session &&
    typeof session.set === 'function' &&
    'unset' in session &&
    typeof session.unset === 'function' &&
    'commit' in session &&
    typeof session.commit === 'function'
  )
}
