/*
 * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
 */

import * as z from "zod/v3";
import { safeParse } from "../lib/schemas.js";
import { ClosedEnum } from "../types/enums.js";
import { Result as SafeParseResult } from "../types/fp.js";
import * as types from "../types/primitives.js";
import { SDKValidationError } from "./sdkvalidationerror.js";
import { VercelError } from "./vercelerror.js";

export const TooManyRequestsCode = {
  TooManyRequests: "too_many_requests",
} as const;
export type TooManyRequestsCode = ClosedEnum<typeof TooManyRequestsCode>;

export type RetryAfter = {
  value: number;
  str: string;
};

export type Limit = {
  total: number;
  remaining: number;
  reset: number;
};

export type TooManyRequestsData = {
  status: number;
  code: TooManyRequestsCode;
  message: string;
  retryAfter: RetryAfter;
  limit: Limit;
};

export class TooManyRequests extends VercelError {
  status: number;
  code: TooManyRequestsCode;
  retryAfter: RetryAfter;
  limit: Limit;

  /** The original data that was passed to this error instance. */
  data$: TooManyRequestsData;

  constructor(
    err: TooManyRequestsData,
    httpMeta: { response: Response; request: Request; body: string },
  ) {
    const message = err.message || `API error occurred: ${JSON.stringify(err)}`;
    super(message, httpMeta);
    this.data$ = err;
    this.status = err.status;
    this.code = err.code;
    this.retryAfter = err.retryAfter;
    this.limit = err.limit;

    this.name = "TooManyRequests";
  }
}

/** @internal */
export const TooManyRequestsCode$inboundSchema: z.ZodNativeEnum<
  typeof TooManyRequestsCode
> = z.nativeEnum(TooManyRequestsCode);

/** @internal */
export const RetryAfter$inboundSchema: z.ZodType<
  RetryAfter,
  z.ZodTypeDef,
  unknown
> = z.object({
  value: types.number(),
  str: types.string(),
});

export function retryAfterFromJSON(
  jsonString: string,
): SafeParseResult<RetryAfter, SDKValidationError> {
  return safeParse(
    jsonString,
    (x) => RetryAfter$inboundSchema.parse(JSON.parse(x)),
    `Failed to parse 'RetryAfter' from JSON`,
  );
}

/** @internal */
export const Limit$inboundSchema: z.ZodType<Limit, z.ZodTypeDef, unknown> = z
  .object({
    total: types.number(),
    remaining: types.number(),
    reset: types.number(),
  });

export function limitFromJSON(
  jsonString: string,
): SafeParseResult<Limit, SDKValidationError> {
  return safeParse(
    jsonString,
    (x) => Limit$inboundSchema.parse(JSON.parse(x)),
    `Failed to parse 'Limit' from JSON`,
  );
}

/** @internal */
export const TooManyRequests$inboundSchema: z.ZodType<
  TooManyRequests,
  z.ZodTypeDef,
  unknown
> = z.object({
  status: types.number(),
  code: TooManyRequestsCode$inboundSchema,
  message: types.string(),
  retryAfter: z.lazy(() => RetryAfter$inboundSchema),
  limit: z.lazy(() => Limit$inboundSchema),
  request$: z.instanceof(Request),
  response$: z.instanceof(Response),
  body$: z.string(),
})
  .transform((v) => {
    return new TooManyRequests(v, {
      request: v.request$,
      response: v.response$,
      body: v.body$,
    });
  });
