// Generated by bynkc — do not edit by hand.
// context kv.index

import { Ok, Err, Some, None, type Result, type Option, type ValidationError, type JsonError, type JsonValue, type BoundaryError } from "../runtime.js";

import * as bynk_cloudflare from "../bynk/cloudflare.js";

export interface Entry {
  readonly sku: string;
  readonly price: number;
  readonly qty: number;
}

export const Entry = {
};

export const scan = {
  async call(prefix: string, deps: { Kv: bynk_cloudflare.Kv }): Promise<Result<readonly string[], void>> {
    const keys = await deps.Kv.list(Some(prefix));
    return Ok(keys);
  },
};

export const cache = {
  async call(key: string, e: Entry, deps: { Kv: bynk_cloudflare.Kv }): Promise<Option<Entry>> {
    const __r0 = await deps.Kv.putTtl(key, JSON.stringify(serialise_Entry(e)), 60);
    const stored = await deps.Kv.get(key);
    switch (stored.tag) {
      case "Some": {
        const s = stored.value;
        return ((__d) => {
    switch (__d.tag) {
      case "Ok": {
        const decoded = __d.value;
        return Some(decoded);
      }
      case "Err": {
        return None;
      }
    }
    throw new Error("non-exhaustive match");
  })(((__s: string): Result<Entry, JsonError> => { let __j: JsonValue; try { __j = JSON.parse(__s) as JsonValue; } catch (__e) { return Err({ kind: "Malformed", path: "$", message: String(__e) }); } const __r = deserialise_Entry(__j, "$"); if (__r.tag === "Ok") return Ok(__r.value as Entry); const __be = __r.error; return Err({ kind: __be.kind, path: (__be.kind === "StructuralMismatch" || __be.kind === "RefinementViolation") ? __be.path : "$", message: __be.kind === "StructuralMismatch" ? `expected ${__be.expected}, got ${String(__be.actual)}` : __be.kind === "RefinementViolation" ? __be.violation.message : __be.details }); })(s));
      }
      case "None": {
        return None;
      }
    }
    throw new Error("non-exhaustive match");
  },
};

export const allKeys = {
  async call(unused: number, deps: { Kv: bynk_cloudflare.Kv }): Promise<Result<readonly string[], void>> {
    const keys = await deps.Kv.list(None);
    return Ok(keys);
  },
};

export interface KvIndexDeps {
  readonly Kv: bynk_cloudflare.Kv;
}

export function makeSurface(deps: KvIndexDeps) {
  return {
    async scan(prefix: string): Promise<Result<readonly string[], void>> {
      return scan.call(prefix, deps);
    },
    async cache(key: string, e: Entry): Promise<Option<Entry>> {
      return cache.call(key, e, deps);
    },
    async allKeys(unused: number): Promise<Result<readonly string[], void>> {
      return allKeys.call(unused, deps);
    },
  };
}

export function serialise_Entry(value: Entry): JsonValue {
  return {
    sku: value.sku as JsonValue,
    price: ((v: number) => { if (!Number.isFinite(v)) throw new Error("non-finite Float at boundary"); return v as JsonValue; })(value.price),
    qty: value.qty as JsonValue,
  };
}

export function deserialise_Entry(json: JsonValue, path: string = "$"): Result<Entry, 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 (typeof obj["sku"] !== "string") {
    return Err({ kind: "StructuralMismatch", path: `${path}.sku`, expected: "string", actual: typeof obj["sku"] });
  }
  const __sku = obj["sku"];
  if (typeof obj["price"] !== "number") {
    return Err({ kind: "StructuralMismatch", path: `${path}.price`, expected: "number", actual: typeof obj["price"] });
  }
  if (!Number.isFinite(obj["price"])) {
    return Err({ kind: "StructuralMismatch", path: `${path}.price`, expected: "finite number", actual: String(obj["price"]) });
  }
  const __price = obj["price"];
  if (typeof obj["qty"] !== "number") {
    return Err({ kind: "StructuralMismatch", path: `${path}.qty`, expected: "number", actual: typeof obj["qty"] });
  }
  if (!Number.isInteger(obj["qty"])) {
    return Err({ kind: "StructuralMismatch", path: `${path}.qty`, expected: "integer", actual: String(obj["qty"]) });
  }
  const __qty = obj["qty"];
  return Ok({ sku: __sku, price: __price, qty: __qty } as Entry);
}


