// Generated by bynkc — do not edit by hand.
// adapter bynk

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

/**
 * A UUID in canonical 8-4-4-4-12 lowercase-hex form.
 */
export type Uuid = string & { readonly __brand: "Uuid" };

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

/**
 * An HTTP request method.
 */
export type Method =
    { readonly tag: "Get" }
  | { readonly tag: "Post" }
  | { readonly tag: "Put" }
  | { readonly tag: "Delete" };

export const Method = {
  Get: { tag: "Get" } as Method,
  Post: { tag: "Post" } as Method,
  Put: { tag: "Put" } as Method,
  Delete: { tag: "Delete" } as Method,
};

/**
 * Why an outbound `Fetch.send` failed: a network error or a timeout.
 */
export type FetchError =
    { readonly tag: "Network" }
  | { readonly tag: "Timeout" };

export const FetchError = {
  Network: { tag: "Network" } as FetchError,
  Timeout: { tag: "Timeout" } as FetchError,
};

/**
 * An outbound HTTP request, as passed to `Fetch.send`.
 */
export interface Request {
  readonly method: Method;
  readonly url: string;
  readonly contentType: Option<string>;
  readonly authorization: Option<string>;
  readonly body: Option<string>;
}

export const Request = {
};

/**
 * An HTTP response: a status code and a body.
 */
export interface Response {
  readonly status: number;
  readonly body: string;
}

export const Response = {
};

/**
 * Reads the current wall-clock time, as Unix milliseconds.
 */
export interface Clock {
  now(): Promise<number>;
}

export const ClockToken: unique symbol = Symbol("Clock");

/**
 * A source of randomness — fresh UUIDs and bounded integers.
 */
export interface Random {
  uuid(): Promise<Uuid>;
  int(lo: number, hi: number): Promise<number>;
}

export const RandomToken: unique symbol = Symbol("Random");

/**
 * Structured logging at info and error levels.
 */
export interface Logger {
  info(msg: string): Promise<void>;
  error(msg: string): Promise<void>;
}

export const LoggerToken: unique symbol = Symbol("Logger");

/**
 * Performs outbound HTTP requests.
 */
export interface Fetch {
  send(req: Request): Promise<Result<Response, FetchError>>;
}

export const FetchToken: unique symbol = Symbol("Fetch");

/**
 * Reads named secrets from the platform's secret store.
 */
export interface Secrets {
  get(name: string): Promise<Option<string>>;
}

export const SecretsToken: unique symbol = Symbol("Secrets");

export function serialise_FetchError(value: FetchError): JsonValue {
  switch (value.tag) {
    case "Network":
      return { kind: "Network" };
    case "Timeout":
      return { kind: "Timeout" };
  }
}

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

export function serialise_Method(value: Method): JsonValue {
  switch (value.tag) {
    case "Get":
      return { kind: "Get" };
    case "Post":
      return { kind: "Post" };
    case "Put":
      return { kind: "Put" };
    case "Delete":
      return { kind: "Delete" };
  }
}

export function deserialise_Method(json: JsonValue, path: string = "$"): Result<Method, 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 "Get":
      return Ok({ tag: "Get" } as Method);
    case "Post":
      return Ok({ tag: "Post" } as Method);
    case "Put":
      return Ok({ tag: "Put" } as Method);
    case "Delete":
      return Ok({ tag: "Delete" } as Method);
    default:
      return Err({ kind: "StructuralMismatch", path, expected: "sum variant kind", actual: String(kind) });
  }
}

export function serialise_Request(value: Request): JsonValue {
  return {
    method: serialise_Method(value.method),
    url: value.url as JsonValue,
    contentType: serialise_Option_String(value.contentType),
    authorization: serialise_Option_String(value.authorization),
    body: serialise_Option_String(value.body),
  };
}

export function deserialise_Request(json: JsonValue, path: string = "$"): Result<Request, 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 __r_method = deserialise_Method(obj["method"], `${path}.method`);
  if (__r_method.tag === "Err") return __r_method;
  const __method = __r_method.value;
  if (typeof obj["url"] !== "string") {
    return Err({ kind: "StructuralMismatch", path: `${path}.url`, expected: "string", actual: typeof obj["url"] });
  }
  const __url = obj["url"];
  const __r_contentType = deserialise_Option_String(obj["contentType"], `${path}.contentType`);
  if (__r_contentType.tag === "Err") return __r_contentType;
  const __contentType = __r_contentType.value;
  const __r_authorization = deserialise_Option_String(obj["authorization"], `${path}.authorization`);
  if (__r_authorization.tag === "Err") return __r_authorization;
  const __authorization = __r_authorization.value;
  const __r_body = deserialise_Option_String(obj["body"], `${path}.body`);
  if (__r_body.tag === "Err") return __r_body;
  const __body = __r_body.value;
  return Ok({ method: __method, url: __url, contentType: __contentType, authorization: __authorization, body: __body } as Request);
}

export function serialise_Response(value: Response): JsonValue {
  return {
    status: value.status as JsonValue,
    body: value.body as JsonValue,
  };
}

export function deserialise_Response(json: JsonValue, path: string = "$"): Result<Response, 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["status"] !== "number") {
    return Err({ kind: "StructuralMismatch", path: `${path}.status`, expected: "number", actual: typeof obj["status"] });
  }
  if (!Number.isInteger(obj["status"])) {
    return Err({ kind: "StructuralMismatch", path: `${path}.status`, expected: "integer", actual: String(obj["status"]) });
  }
  const __status = obj["status"];
  if (typeof obj["body"] !== "string") {
    return Err({ kind: "StructuralMismatch", path: `${path}.body`, expected: "string", actual: typeof obj["body"] });
  }
  const __body = obj["body"];
  return Ok({ status: __status, body: __body } as Response);
}

export function serialise_Uuid(value: Uuid): JsonValue {
  return value as unknown as string;
}

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


export function serialise_Option_String(value: Option<string>): JsonValue {
  if (value.tag === "Some") return { kind: "Some", value: value.value as JsonValue };
  return { kind: "None" };
}

export function deserialise_Option_String(json: JsonValue, path: string = "$"): Result<Option<string>, 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"] === "Some") {
  if (typeof obj["value"] !== "string") {
    return Err({ kind: "StructuralMismatch", path: `${path}.value`, expected: "string", actual: typeof obj["value"] });
  }
  const __v = obj["value"];
    return Ok(Some(__v) as Option<string>);
  } else if (obj["kind"] === "None") {
    return Ok(None as Option<string>);
  }
  return Err({ kind: "StructuralMismatch", path, expected: "Some | None", actual: String(obj["kind"]) });
}

