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

import * as z from "zod/v3";
import { remap as remap$ } from "../lib/primitives.js";
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";

export type ApproveRollingReleaseStageRequestBody = {
  /**
   * The index of the stage to transition to
   */
  nextStageIndex: number;
  /**
   * The id of the canary deployment to approve for the next stage
   */
  canaryDeploymentId: string;
};

export type ApproveRollingReleaseStageRequest = {
  /**
   * Project ID or project name (URL-encoded)
   */
  idOrName: string;
  /**
   * The Team identifier to perform the request on behalf of.
   */
  teamId?: string | undefined;
  /**
   * The Team slug to perform the request on behalf of.
   */
  slug?: string | undefined;
  requestBody?: ApproveRollingReleaseStageRequestBody | undefined;
};

/**
 * The current state of the rolling release
 */
export const ApproveRollingReleaseStageState = {
  Aborted: "ABORTED",
  Active: "ACTIVE",
  Complete: "COMPLETE",
} as const;
/**
 * The current state of the rolling release
 */
export type ApproveRollingReleaseStageState = ClosedEnum<
  typeof ApproveRollingReleaseStageState
>;

/**
 * When set to `PAUSED`, the rollout is frozen at the current percentage until continued.
 */
export const ApproveRollingReleaseStageSubstate = {
  Paused: "PAUSED",
} as const;
/**
 * When set to `PAUSED`, the rollout is frozen at the current percentage until continued.
 */
export type ApproveRollingReleaseStageSubstate = ClosedEnum<
  typeof ApproveRollingReleaseStageSubstate
>;

/**
 * If defined, either `staging` if a staging alias in the format `<project>.<team>.now.sh` was assigned upon creation, or `production` if the aliases from `alias` were assigned. `null` value indicates the "preview" deployment.
 */
export const ApproveRollingReleaseStageTarget = {
  Production: "production",
  Staging: "staging",
} as const;
/**
 * If defined, either `staging` if a staging alias in the format `<project>.<team>.now.sh` was assigned upon creation, or `production` if the aliases from `alias` were assigned. `null` value indicates the "preview" deployment.
 */
export type ApproveRollingReleaseStageTarget = ClosedEnum<
  typeof ApproveRollingReleaseStageTarget
>;

/**
 * The state of the deployment depending on the process of deploying, or if it is ready or in an error state
 */
export const ApproveRollingReleaseStageReadyState = {
  Blocked: "BLOCKED",
  Building: "BUILDING",
  Canceled: "CANCELED",
  Error: "ERROR",
  Initializing: "INITIALIZING",
  Queued: "QUEUED",
  Ready: "READY",
} as const;
/**
 * The state of the deployment depending on the process of deploying, or if it is ready or in an error state
 */
export type ApproveRollingReleaseStageReadyState = ClosedEnum<
  typeof ApproveRollingReleaseStageReadyState
>;

/**
 * Where was the deployment created from. Best-effort guess for metrics only — not authoritative; do not gate behavior on it.
 */
export const ApproveRollingReleaseStageSource = {
  ApiTriggerGitDeploy: "api-trigger-git-deploy",
  Cli: "cli",
  CloneRepo: "clone/repo",
  Drop: "drop",
  Git: "git",
  Import: "import",
  ImportRepo: "import/repo",
  Redeploy: "redeploy",
  V0Web: "v0-web",
} as const;
/**
 * Where was the deployment created from. Best-effort guess for metrics only — not authoritative; do not gate behavior on it.
 */
export type ApproveRollingReleaseStageSource = ClosedEnum<
  typeof ApproveRollingReleaseStageSource
>;

/**
 * The current deployment receiving production traffic
 */
export type ApproveRollingReleaseStageCurrentDeployment = {
  /**
   * The name of the project associated with the deployment at the time that the deployment was created
   */
  name: string;
  /**
   * A number containing the date when the deployment was created in milliseconds
   */
  createdAt: number;
  /**
   * A string holding the unique ID of the deployment
   */
  id: string;
  /**
   * If defined, either `staging` if a staging alias in the format `<project>.<team>.now.sh` was assigned upon creation, or `production` if the aliases from `alias` were assigned. `null` value indicates the "preview" deployment.
   */
  target?: ApproveRollingReleaseStageTarget | null | undefined;
  /**
   * The state of the deployment depending on the process of deploying, or if it is ready or in an error state
   */
  readyState: ApproveRollingReleaseStageReadyState;
  readyStateAt?: number | undefined;
  /**
   * Where was the deployment created from. Best-effort guess for metrics only — not authoritative; do not gate behavior on it.
   */
  source?: ApproveRollingReleaseStageSource | undefined;
  /**
   * A string with the unique URL of the deployment
   */
  url: string;
};

/**
 * If defined, either `staging` if a staging alias in the format `<project>.<team>.now.sh` was assigned upon creation, or `production` if the aliases from `alias` were assigned. `null` value indicates the "preview" deployment.
 */
export const ApproveRollingReleaseStageRollingReleaseTarget = {
  Production: "production",
  Staging: "staging",
} as const;
/**
 * If defined, either `staging` if a staging alias in the format `<project>.<team>.now.sh` was assigned upon creation, or `production` if the aliases from `alias` were assigned. `null` value indicates the "preview" deployment.
 */
export type ApproveRollingReleaseStageRollingReleaseTarget = ClosedEnum<
  typeof ApproveRollingReleaseStageRollingReleaseTarget
>;

/**
 * The state of the deployment depending on the process of deploying, or if it is ready or in an error state
 */
export const ApproveRollingReleaseStageRollingReleaseReadyState = {
  Blocked: "BLOCKED",
  Building: "BUILDING",
  Canceled: "CANCELED",
  Error: "ERROR",
  Initializing: "INITIALIZING",
  Queued: "QUEUED",
  Ready: "READY",
} as const;
/**
 * The state of the deployment depending on the process of deploying, or if it is ready or in an error state
 */
export type ApproveRollingReleaseStageRollingReleaseReadyState = ClosedEnum<
  typeof ApproveRollingReleaseStageRollingReleaseReadyState
>;

/**
 * Where was the deployment created from. Best-effort guess for metrics only — not authoritative; do not gate behavior on it.
 */
export const ApproveRollingReleaseStageRollingReleaseSource = {
  ApiTriggerGitDeploy: "api-trigger-git-deploy",
  Cli: "cli",
  CloneRepo: "clone/repo",
  Drop: "drop",
  Git: "git",
  Import: "import",
  ImportRepo: "import/repo",
  Redeploy: "redeploy",
  V0Web: "v0-web",
} as const;
/**
 * Where was the deployment created from. Best-effort guess for metrics only — not authoritative; do not gate behavior on it.
 */
export type ApproveRollingReleaseStageRollingReleaseSource = ClosedEnum<
  typeof ApproveRollingReleaseStageRollingReleaseSource
>;

/**
 * The canary deployment being rolled out
 */
export type ApproveRollingReleaseStageCanaryDeployment = {
  /**
   * The name of the project associated with the deployment at the time that the deployment was created
   */
  name: string;
  /**
   * A number containing the date when the deployment was created in milliseconds
   */
  createdAt: number;
  /**
   * A string holding the unique ID of the deployment
   */
  id: string;
  /**
   * If defined, either `staging` if a staging alias in the format `<project>.<team>.now.sh` was assigned upon creation, or `production` if the aliases from `alias` were assigned. `null` value indicates the "preview" deployment.
   */
  target?: ApproveRollingReleaseStageRollingReleaseTarget | null | undefined;
  /**
   * The state of the deployment depending on the process of deploying, or if it is ready or in an error state
   */
  readyState: ApproveRollingReleaseStageRollingReleaseReadyState;
  readyStateAt?: number | undefined;
  /**
   * Where was the deployment created from. Best-effort guess for metrics only — not authoritative; do not gate behavior on it.
   */
  source?: ApproveRollingReleaseStageRollingReleaseSource | undefined;
  /**
   * A string with the unique URL of the deployment
   */
  url: string;
};

/**
 * The advancement type of the rolling release
 */
export const ApproveRollingReleaseStageAdvancementType = {
  Automatic: "automatic",
  ManualApproval: "manual-approval",
} as const;
/**
 * The advancement type of the rolling release
 */
export type ApproveRollingReleaseStageAdvancementType = ClosedEnum<
  typeof ApproveRollingReleaseStageAdvancementType
>;

/**
 * All stages configured for this rolling release
 */
export type ApproveRollingReleaseStageStages = {
  /**
   * The zero-based index of the stage
   */
  index: number;
  /**
   * Whether or not this stage is the final stage (targetPercentage === 100)
   */
  isFinalStage: boolean;
  /**
   * The percentage of traffic to serve to the canary deployment (0-100)
   */
  targetPercentage: number;
  /**
   * Whether or not this stage requires manual approval to proceed
   */
  requireApproval: boolean;
  /**
   * Duration in seconds for automatic advancement, null for manual stages or the final stage
   */
  duration: number | null;
  /**
   * Whether to linearly shift traffic over the duration of this stage
   */
  linearShift?: boolean | undefined;
};

/**
 * The currently active stage, null if the rollout is aborted
 */
export type ApproveRollingReleaseStageActiveStage = {
  /**
   * The zero-based index of the stage
   */
  index: number;
  /**
   * Whether or not this stage is the final stage (targetPercentage === 100)
   */
  isFinalStage: boolean;
  /**
   * The percentage of traffic to serve to the canary deployment (0-100)
   */
  targetPercentage: number;
  /**
   * Whether or not this stage requires manual approval to proceed
   */
  requireApproval: boolean;
  /**
   * Duration in seconds for automatic advancement, null for manual stages or the final stage
   */
  duration: number | null;
  /**
   * Whether to linearly shift traffic over the duration of this stage
   */
  linearShift?: boolean | undefined;
};

/**
 * The next stage to be activated, null if not in ACTIVE state
 */
export type ApproveRollingReleaseStageNextStage = {
  /**
   * The zero-based index of the stage
   */
  index: number;
  /**
   * Whether or not this stage is the final stage (targetPercentage === 100)
   */
  isFinalStage: boolean;
  /**
   * The percentage of traffic to serve to the canary deployment (0-100)
   */
  targetPercentage: number;
  /**
   * Whether or not this stage requires manual approval to proceed
   */
  requireApproval: boolean;
  /**
   * Duration in seconds for automatic advancement, null for manual stages or the final stage
   */
  duration: number | null;
  /**
   * Whether to linearly shift traffic over the duration of this stage
   */
  linearShift?: boolean | undefined;
};

/**
 * Rolling release information including configuration and document details, or null if no rolling release exists
 */
export type ApproveRollingReleaseStageRollingRelease = {
  /**
   * The current state of the rolling release
   */
  state: ApproveRollingReleaseStageState;
  /**
   * When set to `PAUSED`, the rollout is frozen at the current percentage until continued.
   */
  substate: ApproveRollingReleaseStageSubstate | null;
  /**
   * The current deployment receiving production traffic
   */
  currentDeployment: ApproveRollingReleaseStageCurrentDeployment | null;
  /**
   * The canary deployment being rolled out
   */
  canaryDeployment: ApproveRollingReleaseStageCanaryDeployment | null;
  /**
   * The ID of a deployment queued for the next rolling release
   */
  queuedDeploymentId: string | null;
  /**
   * The advancement type of the rolling release
   */
  advancementType: ApproveRollingReleaseStageAdvancementType;
  /**
   * All stages configured for this rolling release
   */
  stages: Array<ApproveRollingReleaseStageStages>;
  /**
   * The currently active stage, null if the rollout is aborted
   */
  activeStage: ApproveRollingReleaseStageActiveStage | null;
  /**
   * The next stage to be activated, null if not in ACTIVE state
   */
  nextStage: ApproveRollingReleaseStageNextStage | null;
  /**
   * Unix timestamp in milliseconds when the rolling release started
   */
  startedAt: number;
  /**
   * Unix timestamp in milliseconds when the rolling release was last updated
   */
  updatedAt: number;
  /**
   * When set (for example while {@link substate} is `PAUSED`), the canary traffic percentage persisted on the rollout document — use for dashboard display when linear shift is active.
   */
  currentCanaryPercentage?: number | undefined;
};

/**
 * The response format for rolling release endpoints that return rolling release information
 */
export type ApproveRollingReleaseStageResponseBody = {
  /**
   * Rolling release information including configuration and document details, or null if no rolling release exists
   */
  rollingRelease: ApproveRollingReleaseStageRollingRelease | null;
};

/** @internal */
export type ApproveRollingReleaseStageRequestBody$Outbound = {
  nextStageIndex: number;
  canaryDeploymentId: string;
};

/** @internal */
export const ApproveRollingReleaseStageRequestBody$outboundSchema: z.ZodType<
  ApproveRollingReleaseStageRequestBody$Outbound,
  z.ZodTypeDef,
  ApproveRollingReleaseStageRequestBody
> = z.object({
  nextStageIndex: z.number(),
  canaryDeploymentId: z.string(),
});

export function approveRollingReleaseStageRequestBodyToJSON(
  approveRollingReleaseStageRequestBody: ApproveRollingReleaseStageRequestBody,
): string {
  return JSON.stringify(
    ApproveRollingReleaseStageRequestBody$outboundSchema.parse(
      approveRollingReleaseStageRequestBody,
    ),
  );
}

/** @internal */
export type ApproveRollingReleaseStageRequest$Outbound = {
  idOrName: string;
  teamId?: string | undefined;
  slug?: string | undefined;
  RequestBody?: ApproveRollingReleaseStageRequestBody$Outbound | undefined;
};

/** @internal */
export const ApproveRollingReleaseStageRequest$outboundSchema: z.ZodType<
  ApproveRollingReleaseStageRequest$Outbound,
  z.ZodTypeDef,
  ApproveRollingReleaseStageRequest
> = z.object({
  idOrName: z.string(),
  teamId: z.string().optional(),
  slug: z.string().optional(),
  requestBody: z.lazy(() =>
    ApproveRollingReleaseStageRequestBody$outboundSchema
  ).optional(),
}).transform((v) => {
  return remap$(v, {
    requestBody: "RequestBody",
  });
});

export function approveRollingReleaseStageRequestToJSON(
  approveRollingReleaseStageRequest: ApproveRollingReleaseStageRequest,
): string {
  return JSON.stringify(
    ApproveRollingReleaseStageRequest$outboundSchema.parse(
      approveRollingReleaseStageRequest,
    ),
  );
}

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

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

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

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

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

/** @internal */
export const ApproveRollingReleaseStageCurrentDeployment$inboundSchema:
  z.ZodType<
    ApproveRollingReleaseStageCurrentDeployment,
    z.ZodTypeDef,
    unknown
  > = z.object({
    name: types.string(),
    createdAt: types.number(),
    id: types.string(),
    target: z.nullable(ApproveRollingReleaseStageTarget$inboundSchema)
      .optional(),
    readyState: ApproveRollingReleaseStageReadyState$inboundSchema,
    readyStateAt: types.optional(types.number()),
    source: types.optional(ApproveRollingReleaseStageSource$inboundSchema),
    url: types.string(),
  });

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

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

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

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

/** @internal */
export const ApproveRollingReleaseStageCanaryDeployment$inboundSchema:
  z.ZodType<ApproveRollingReleaseStageCanaryDeployment, z.ZodTypeDef, unknown> =
    z.object({
      name: types.string(),
      createdAt: types.number(),
      id: types.string(),
      target: z.nullable(
        ApproveRollingReleaseStageRollingReleaseTarget$inboundSchema,
      ).optional(),
      readyState:
        ApproveRollingReleaseStageRollingReleaseReadyState$inboundSchema,
      readyStateAt: types.optional(types.number()),
      source: types.optional(
        ApproveRollingReleaseStageRollingReleaseSource$inboundSchema,
      ),
      url: types.string(),
    });

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

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

/** @internal */
export const ApproveRollingReleaseStageStages$inboundSchema: z.ZodType<
  ApproveRollingReleaseStageStages,
  z.ZodTypeDef,
  unknown
> = z.object({
  index: types.number(),
  isFinalStage: types.boolean(),
  targetPercentage: types.number(),
  requireApproval: types.boolean(),
  duration: types.nullable(types.number()),
  linearShift: types.optional(types.boolean()),
});

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

/** @internal */
export const ApproveRollingReleaseStageActiveStage$inboundSchema: z.ZodType<
  ApproveRollingReleaseStageActiveStage,
  z.ZodTypeDef,
  unknown
> = z.object({
  index: types.number(),
  isFinalStage: types.boolean(),
  targetPercentage: types.number(),
  requireApproval: types.boolean(),
  duration: types.nullable(types.number()),
  linearShift: types.optional(types.boolean()),
});

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

/** @internal */
export const ApproveRollingReleaseStageNextStage$inboundSchema: z.ZodType<
  ApproveRollingReleaseStageNextStage,
  z.ZodTypeDef,
  unknown
> = z.object({
  index: types.number(),
  isFinalStage: types.boolean(),
  targetPercentage: types.number(),
  requireApproval: types.boolean(),
  duration: types.nullable(types.number()),
  linearShift: types.optional(types.boolean()),
});

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

/** @internal */
export const ApproveRollingReleaseStageRollingRelease$inboundSchema: z.ZodType<
  ApproveRollingReleaseStageRollingRelease,
  z.ZodTypeDef,
  unknown
> = z.object({
  state: ApproveRollingReleaseStageState$inboundSchema,
  substate: types.nullable(ApproveRollingReleaseStageSubstate$inboundSchema),
  currentDeployment: types.nullable(
    z.lazy(() => ApproveRollingReleaseStageCurrentDeployment$inboundSchema),
  ),
  canaryDeployment: types.nullable(
    z.lazy(() => ApproveRollingReleaseStageCanaryDeployment$inboundSchema),
  ),
  queuedDeploymentId: types.nullable(types.string()),
  advancementType: ApproveRollingReleaseStageAdvancementType$inboundSchema,
  stages: z.array(z.lazy(() => ApproveRollingReleaseStageStages$inboundSchema)),
  activeStage: types.nullable(
    z.lazy(() => ApproveRollingReleaseStageActiveStage$inboundSchema),
  ),
  nextStage: types.nullable(
    z.lazy(() => ApproveRollingReleaseStageNextStage$inboundSchema),
  ),
  startedAt: types.number(),
  updatedAt: types.number(),
  currentCanaryPercentage: types.optional(types.number()),
});

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

/** @internal */
export const ApproveRollingReleaseStageResponseBody$inboundSchema: z.ZodType<
  ApproveRollingReleaseStageResponseBody,
  z.ZodTypeDef,
  unknown
> = z.object({
  rollingRelease: types.nullable(
    z.lazy(() => ApproveRollingReleaseStageRollingRelease$inboundSchema),
  ),
});

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