// Generated by bynkc — do not edit by hand.
// bynk surface binding for the `browser` platform.
import type { Clock, Fetch, Logger, Random, Secrets } from "./bynk.js";
import type { Request as FetchRequest, Response as FetchResponse } from "./bynk.js";
import type { FetchError } from "./bynk.js";
import { Uuid } from "./bynk.js";
import type { Option, Result } from "./runtime.js";

// Clock, Random, and Logger are identical to the Node binding: `Date.now()`,
// Web Crypto's `crypto.randomUUID()`, `Math.random()`, and `console` are all Web
// standards present in the browser — the ambient-surface portability claim
// (spec §4.2) holds across Node, Cloudflare, and the browser unchanged.
export class ClockProvider implements Clock {
  async now(): Promise<number> {
    return Date.now();
  }
}

export class RandomProvider implements Random {
  async uuid(): Promise<Uuid> {
    const r = Uuid.of(crypto.randomUUID());
    if (r.tag === "Err") {
      throw new Error("unreachable: crypto.randomUUID() yields a valid UUID");
    }
    return r.value;
  }
  async int(lo: number, hi: number): Promise<number> {
    return lo + Math.floor(Math.random() * (hi - lo));
  }
}

export class LoggerProvider implements Logger {
  async info(msg: string): Promise<void> {
    console.log(msg);
  }
  async error(msg: string): Promise<void> {
    console.error(msg);
  }
}

// Fetch is **withheld** in the browser playground (in-browser track §4, Q2): a
// browser *can* `fetch`, but arbitrary outbound requests from the playground
// origin invite SSRF and exfil-by-proxy, so the binding refuses it. `FetchError`
// has no capability-unavailable variant (adding one is a breaking surface
// change), so a withheld call **fails loudly by throwing** rather than
// masquerading as a transient `Network` error a program might retry. A
// same-origin proxied or opt-in "advanced" Fetch is the named follow-on.
export class FetchProvider implements Fetch {
  async send(_req: FetchRequest): Promise<Result<FetchResponse, FetchError>> {
    throw new Error(
      "bynk.Fetch is unavailable in the browser playground: outbound HTTP is withheld for safety. Run the program on a platform that provides Fetch (node or cloudflare).",
    );
  }
}

// A browser has no `process.env` or any secret store. Resolving to `None` would be
// indistinguishable from "secret not set" — a silent way to run with blank values —
// so `get` **fails loudly** instead, surfacing the missing capability rather than
// hiding it. (Accepts the compose-injected env to match the surface's provider
// construction, then ignores it — there is nothing to read.)
export class SecretsProvider implements Secrets {
  constructor(_env?: unknown) {}
  async get(_name: string): Promise<Option<string>> {
    throw new Error(
      "bynk.Secrets is unavailable in the browser playground: there is no secret store. Run the program on a platform that provides Secrets (node or cloudflare).",
    );
  }
}
