// Generated by bynkc — do not edit by hand.
// context demo.counter

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

/**
 * A minimal stateful agent in the bundle target: instantiation lowers through the
 * generated factory, the method call is a direct call, and state persists per key
 * across calls within a session.
 */

export type CounterId = string & { readonly __brand: "demo.counter.CounterId" };

export const CounterId = {
  of(value: string): Result<CounterId, ValidationError> {
    if (!new RegExp("^" + "[a-z0-9]{1,16}" + "$").test(value)) {
      return Err({ field: "CounterId", message: "must match /[a-z0-9]{1,16}/", value });
    }
    return Ok(value as CounterId);
  },
  unsafe(value: string): CounterId {
    return value as CounterId;
  },
};

export type CounterError =
    { readonly tag: "Overflow" };

export const CounterError = {
  Overflow: { tag: "Overflow" } as CounterError,
};

export interface CounterState {
  readonly count: number;
}

const __CounterRegistry = new StateRegistry();
function __zeroOfCounterState(): CounterState { return { count: 0 }; }

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

  private async loadState(): Promise<CounterState> {
    const stored = await this.state.storage.get<CounterState>("state");
    return stored ?? __zeroOfCounterState();
  }

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

  async increment(deps: {}): Promise<Result<number, CounterError>> {
    const currentState = await this.loadState();
    const next = currentState.count + 1;
    await this.commitState({ ...currentState, count: next });
    return Ok(next);
  }

  async current(deps: {}): Promise<Result<number, CounterError>> {
    const currentState = await this.loadState();
    return Ok(currentState.count);
  }

  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);
    if (url.pathname.startsWith("/_bynk/agent/")) {
      const methodName = url.pathname.slice("/_bynk/agent/".length);
      const { args, deps } = (await request.json()) as { args: unknown[]; deps: unknown };
      const result = await (this as any)[methodName](...args, deps);
      return new Response(JSON.stringify(result), { headers: { "content-type": "application/json" } });
    }
    return new Response("Not Found", { status: 404 });
  }

}

export function __makeCounter(key: CounterId, env?: { COUNTER?: DurableObjectNamespace }): Counter {
  return makeAgent(__CounterRegistry, env?.COUNTER, key, (state) => new Counter(state));
}

export const bump = {
  async call(id: CounterId, deps: { env: { COUNTER: DurableObjectNamespace } }): Promise<Result<number, CounterError>> {
    const counter = __makeCounter(id, deps.env);
    const total = await counter.increment(deps);
    return total;
  },
};

export const read = {
  async call(id: CounterId, deps: { env: { COUNTER: DurableObjectNamespace } }): Promise<Result<number, CounterError>> {
    const counter = __makeCounter(id, deps.env);
    const total = await counter.current(deps);
    return total;
  },
};

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

export function serialise_CounterError(value: CounterError): JsonValue {
  switch (value.tag) {
    case "Overflow":
      return { kind: "Overflow" };
  }
}

export function deserialise_CounterError(json: JsonValue, path: string = "$"): Result<CounterError, 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 "Overflow":
      return Ok({ tag: "Overflow" } as CounterError);
    default:
      return Err({ kind: "StructuralMismatch", path, expected: "sum variant kind", actual: String(kind) });
  }
}

export function serialise_CounterId(value: CounterId): JsonValue {
  return value as unknown as string;
}

export function deserialise_CounterId(json: JsonValue, path: string = "$"): Result<CounterId, BoundaryError> {
  if (typeof json !== "string") {
    return Err({ kind: "StructuralMismatch", path, expected: "string", actual: typeof json });
  }
  const validated = (typeof (CounterId as any).of === "function")
    ? (CounterId as any).of(json)
    : Ok(json as unknown as CounterId);
  if (validated.tag === "Err") {
    return Err({ kind: "RefinementViolation", path, violation: validated.error });
  }
  return Ok(validated.value as CounterId);
}


export function serialise_Result_Int_CounterError(value: Result<number, CounterError>): JsonValue {
  if (value.tag === "Ok") return { kind: "Ok", value: value.value as JsonValue };
  return { kind: "Err", error: serialise_CounterError(value.error) };
}

export function deserialise_Result_Int_CounterError(json: JsonValue, path: string = "$"): Result<Result<number, CounterError>, 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 };
  if (obj["kind"] === "Ok") {
  if (typeof obj["value"] !== "number") {
    return Err({ kind: "StructuralMismatch", path: `${path}.value`, expected: "number", actual: typeof obj["value"] });
  }
  if (!Number.isInteger(obj["value"])) {
    return Err({ kind: "StructuralMismatch", path: `${path}.value`, expected: "integer", actual: String(obj["value"]) });
  }
  const __v = obj["value"];
    return Ok(Ok(__v) as Result<number, CounterError>);
  } else if (obj["kind"] === "Err") {
  const __r_e = deserialise_CounterError(obj["error"], `${path}.error`);
  if (__r_e.tag === "Err") return __r_e;
  const __e = __r_e.value;
    return Ok(Err(__e) as Result<number, CounterError>);
  }
  return Err({ kind: "StructuralMismatch", path, expected: "Ok | Err", actual: String(obj["kind"]) });
}

