import { randomBytes } from 'node:crypto';
import V3_PATH_PARAMETER_SCHEMAS from './path-parameter-schemas.json' assert { type: 'json' };

export { V3_PATH_PARAMETER_SCHEMAS };
export const V3_UINT = new RegExp(V3_PATH_PARAMETER_SCHEMAS.bondId.pattern);
export const V3_ADDRESS = /^0x[0-9a-f]{40}$/;
export const V3_BYTES32 = new RegExp(V3_PATH_PARAMETER_SCHEMAS.evidenceHash.pattern);
export const V3_IDENTIFIER = /^[A-Za-z0-9][A-Za-z0-9._:-]{7,159}$/;
export const V3_CONTRACT_NAME = new RegExp(V3_PATH_PARAMETER_SCHEMAS.name.pattern);
/** `v3r_` plus a server-generated 128-bit random value in canonical lowercase hex. */
export const V3_REQUEST_ID_SOURCE = V3_PATH_PARAMETER_SCHEMAS.requestId.pattern.slice(1, -1);
export const V3_REQUEST_ID = new RegExp(`^${V3_REQUEST_ID_SOURCE}$`);
export const V3_REQUEST_ID_EXAMPLE = 'v3r_0123456789abcdef0123456789abcdef';

export function isValidV3RequestId(value: string): boolean {
  const schema = V3_PATH_PARAMETER_SCHEMAS.requestId;
  return (
    value.length >= schema.minLength &&
    value.length <= schema.maxLength &&
    new RegExp(schema.pattern).test(value)
  );
}

export function createV3RequestId(): string {
  return `v3r_${randomBytes(16).toString('hex')}`;
}

if (!isValidV3RequestId(V3_REQUEST_ID_EXAMPLE)) {
  throw new Error('V3 request ID example must satisfy the shared request ID constraint');
}

export function strictV3Query(request: Request, required: readonly string[]): URLSearchParams | null {
  const query = new URL(request.url).searchParams;
  const allowed = new Set(required);
  for (const key of query.keys()) if (!allowed.has(key) || query.getAll(key).length !== 1) return null;
  for (const key of required) if (query.getAll(key).length !== 1) return null;
  return query;
}
