import { timingSafeEqual } from "node:crypto";

export type NetworkId = "global";

// The single network today. Centralized so the gateway and the MCP server agree on
// the registry key (the future multi-network swap touches only resolveNetwork).
export const GLOBAL_NETWORK_ID: NetworkId = "global";

// The single future swap-point: credential -> network home. Today it also owns the
// password gate. Returns the network id for a valid secret, or null = unauthorized.
//   - password unset/empty  => auth disabled, any secret (or none) maps to "global"
//   - password set          => secret must match exactly, else null
export function resolveNetwork(
  secret: string | undefined,
  password: string | undefined,
): NetworkId | null {
  if (password === undefined || password === "") {
    return GLOBAL_NETWORK_ID;
  }
  if (secret === undefined) {
    return null;
  }
  return constantTimeEqual(secret, password) ? GLOBAL_NETWORK_ID : null;
}

// Length-guarded constant-time compare. timingSafeEqual throws on unequal-length
// buffers, so the length check is unavoidable and itself leaks only the secret's
// byte length (not its content) — acceptable for a 256-bit random shared secret.
function constantTimeEqual(a: string, b: string): boolean {
  const bufA = Buffer.from(a, "utf8");
  const bufB = Buffer.from(b, "utf8");
  if (bufA.length !== bufB.length) {
    return false;
  }
  return timingSafeEqual(bufA, bufB);
}
