// Generated by bynkc — do not edit by hand.
// context turnstile

import { Ok, Err, Some, None, type Result, type Option, type ValidationError, type DurableObjectState, type DurableObjectNamespace, StateRegistry, makeAgent, rehydrationViolation, type JsonValue, type BoundaryError } from "./runtime.js";

export type Gate =
    { readonly tag: "Locked" }
  | { readonly tag: "Unlocked" };

export const Gate = {
  Locked: { tag: "Locked" } as Gate,
  Unlocked: { tag: "Unlocked" } as Gate,
};

export interface TurnstileState {
  readonly gate: Gate;
}

const __TurnstileRegistry = new StateRegistry();
function __zeroOfTurnstileState(): TurnstileState { return { gate: Gate.Locked }; }

function __rehydrateTurnstileState(s: TurnstileState): void {
  { const __r = deserialise_Gate((s.gate as unknown as JsonValue), "gate"); if (__r.tag === "Err") throw rehydrationViolation("Turnstile", __r.error); }
}

export class Turnstile {
  state: DurableObjectState;
  constructor(state: DurableObjectState) {
    this.state = state;
  }

  private async loadState(): Promise<TurnstileState> {
    const stored = await this.state.storage.get<TurnstileState>("state");
    if (stored === undefined) return __zeroOfTurnstileState();
    const __merged = { ...__zeroOfTurnstileState(), ...stored };
    __rehydrateTurnstileState(__merged);
    return __merged;
  }

  private async commitState(s: TurnstileState): Promise<void> {
    await this.state.storage.put("state", s);
  }

  async unlock(deps: {}): Promise<Result<void, string>> {
    const __state = { ...(await this.loadState()) };
    const __result = await (async () => {
      __state.gate = Gate.Unlocked;
      return Ok(undefined);
    })();
    await this.commitState(__state);
    return __result;
  }

}

export function __makeTurnstile(key: string, env?: { TURNSTILE?: DurableObjectNamespace }): Turnstile {
  return makeAgent(__TurnstileRegistry, env?.TURNSTILE, key, (state) => new Turnstile(state));
}

export function __resetAgents(): void {
  __TurnstileRegistry.reset();
}

export function serialise_Gate(value: Gate): JsonValue {
  switch (value.tag) {
    case "Locked":
      return { kind: "Locked" };
    case "Unlocked":
      return { kind: "Unlocked" };
  }
}

export function deserialise_Gate(json: JsonValue, path: string = "$"): Result<Gate, BoundaryError> {
  if (typeof json !== "object" || json === null || Array.isArray(json)) {
    return Err({ kind: "StructuralMismatch", path, expected: "object", actual: typeof json });
  }
  const obj = json as { [k: string]: JsonValue };
  const kind = obj["kind"];
  switch (kind) {
    case "Locked":
      return Ok({ tag: "Locked" } as Gate);
    case "Unlocked":
      return Ok({ tag: "Unlocked" } as Gate);
    default:
      return Err({ kind: "StructuralMismatch", path, expected: "sum variant kind", actual: String(kind) });
  }
}


