/*
 * 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 { smartUnion } from "../types/smartUnion.js";
import { SDKValidationError } from "./sdkvalidationerror.js";

export const SegmentOutcomeDataRulesType = {
  Entity: "entity",
} as const;
export type SegmentOutcomeDataRulesType = ClosedEnum<
  typeof SegmentOutcomeDataRulesType
>;

export type SegmentOutcomeBase = {
  type: SegmentOutcomeDataRulesType;
  kind: string;
  attribute: string;
};

export type SegmentOutcome2 = {
  type: "split";
  base: SegmentOutcomeBase;
  passPromille: number;
};

export type SegmentOutcome1 = {
  type: "all";
};

export type SegmentOutcome = SegmentOutcome1 | SegmentOutcome2;

export const SegmentRhsDataType = {
  Regex: "regex",
} as const;
export type SegmentRhsDataType = ClosedEnum<typeof SegmentRhsDataType>;

export type SegmentRhs4 = {
  type: SegmentRhsDataType;
  pattern: string;
  flags: string;
};

export const SegmentRhsType = {
  List: "list",
  ListInline: "list/inline",
} as const;
export type SegmentRhsType = ClosedEnum<typeof SegmentRhsType>;

export type SegmentItems2 = {
  label?: string | undefined;
  note?: string | undefined;
  value: string;
};

export type SegmentItems1 = {
  label?: string | undefined;
  note?: string | undefined;
  value: number;
};

export type SegmentRhsItems = SegmentItems1 | SegmentItems2;

export type SegmentRhs3 = {
  type: SegmentRhsType;
  items: Array<SegmentItems1 | SegmentItems2>;
};

export type SegmentRhs = SegmentRhs4 | SegmentRhs3 | string | number | boolean;

export type SegmentCmpOptions = {
  ignoreCase?: boolean | undefined;
};

export type SegmentLhs2 = {
  type: "entity";
  kind: string;
  attribute: string;
};

export type SegmentLhs1 = {
  type: "segment";
};

export type SegmentLhs = SegmentLhs1 | SegmentLhs2;

export const SegmentCmp = {
  NotContains: "!contains",
  NotEndsWith: "!endsWith",
  NotEq: "!eq",
  NotEx: "!ex",
  NotOneOf: "!oneOf",
  NotRegex: "!regex",
  NotStartsWith: "!startsWith",
  After: "after",
  Before: "before",
  Contains: "contains",
  ContainsAllOf: "containsAllOf",
  ContainsAnyOf: "containsAnyOf",
  ContainsNoneOf: "containsNoneOf",
  EndsWith: "endsWith",
  Eq: "eq",
  Ex: "ex",
  Gt: "gt",
  Gte: "gte",
  Lt: "lt",
  Lte: "lte",
  OneOf: "oneOf",
  Regex: "regex",
  StartsWith: "startsWith",
} as const;
export type SegmentCmp = ClosedEnum<typeof SegmentCmp>;

export type SegmentConditions = {
  rhs?: SegmentRhs4 | SegmentRhs3 | string | number | boolean | undefined;
  cmpOptions?: SegmentCmpOptions | undefined;
  lhs: SegmentLhs1 | SegmentLhs2;
  cmp: SegmentCmp;
};

export type SegmentRules = {
  id: string;
  outcome: SegmentOutcome1 | SegmentOutcome2;
  conditions: Array<SegmentConditions>;
};

export type Include = {
  note?: string | undefined;
  value: string;
};

export type ExcludeT = {
  note?: string | undefined;
  value: string;
};

export type Data = {
  rules?: Array<SegmentRules> | undefined;
  include?: { [k: string]: { [k: string]: Array<Include> } } | undefined;
  exclude?: { [k: string]: { [k: string]: Array<ExcludeT> } } | undefined;
};

export const SegmentTypeName = {
  Segment: "segment",
} as const;
export type SegmentTypeName = ClosedEnum<typeof SegmentTypeName>;

export type SegmentCreator = {
  id: string;
  name: string;
};

export type SegmentMetadata = {
  creator?: SegmentCreator | undefined;
};

export type Segment = {
  description?: string | undefined;
  createdBy?: string | undefined;
  usedByFlags?: Array<string> | undefined;
  usedBySegments?: Array<string> | undefined;
  data: Data;
  id: string;
  label: string;
  slug: string;
  createdAt: number;
  updatedAt: number;
  projectId: string;
  typeName: SegmentTypeName;
  hint: string;
  metadata?: SegmentMetadata | undefined;
};

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

/** @internal */
export const SegmentOutcomeBase$inboundSchema: z.ZodType<
  SegmentOutcomeBase,
  z.ZodTypeDef,
  unknown
> = z.object({
  type: SegmentOutcomeDataRulesType$inboundSchema,
  kind: types.string(),
  attribute: types.string(),
});

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

/** @internal */
export const SegmentOutcome2$inboundSchema: z.ZodType<
  SegmentOutcome2,
  z.ZodTypeDef,
  unknown
> = z.object({
  type: types.literal("split"),
  base: z.lazy(() => SegmentOutcomeBase$inboundSchema),
  passPromille: types.number(),
});

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

/** @internal */
export const SegmentOutcome1$inboundSchema: z.ZodType<
  SegmentOutcome1,
  z.ZodTypeDef,
  unknown
> = z.object({
  type: types.literal("all"),
});

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

/** @internal */
export const SegmentOutcome$inboundSchema: z.ZodType<
  SegmentOutcome,
  z.ZodTypeDef,
  unknown
> = z.union([
  z.lazy(() => SegmentOutcome1$inboundSchema),
  z.lazy(() => SegmentOutcome2$inboundSchema),
]);

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

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

/** @internal */
export const SegmentRhs4$inboundSchema: z.ZodType<
  SegmentRhs4,
  z.ZodTypeDef,
  unknown
> = z.object({
  type: SegmentRhsDataType$inboundSchema,
  pattern: types.string(),
  flags: types.string(),
});

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

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

/** @internal */
export const SegmentItems2$inboundSchema: z.ZodType<
  SegmentItems2,
  z.ZodTypeDef,
  unknown
> = z.object({
  label: types.optional(types.string()),
  note: types.optional(types.string()),
  value: types.string(),
});

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

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

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

/** @internal */
export const SegmentRhsItems$inboundSchema: z.ZodType<
  SegmentRhsItems,
  z.ZodTypeDef,
  unknown
> = smartUnion([
  z.lazy(() => SegmentItems1$inboundSchema),
  z.lazy(() => SegmentItems2$inboundSchema),
]);

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

/** @internal */
export const SegmentRhs3$inboundSchema: z.ZodType<
  SegmentRhs3,
  z.ZodTypeDef,
  unknown
> = z.object({
  type: SegmentRhsType$inboundSchema,
  items: z.array(
    smartUnion([
      z.lazy(() => SegmentItems1$inboundSchema),
      z.lazy(() => SegmentItems2$inboundSchema),
    ]),
  ),
});

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

/** @internal */
export const SegmentRhs$inboundSchema: z.ZodType<
  SegmentRhs,
  z.ZodTypeDef,
  unknown
> = smartUnion([
  z.lazy(() => SegmentRhs4$inboundSchema),
  z.lazy(() => SegmentRhs3$inboundSchema),
  types.string(),
  types.number(),
  types.boolean(),
]);

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

/** @internal */
export const SegmentCmpOptions$inboundSchema: z.ZodType<
  SegmentCmpOptions,
  z.ZodTypeDef,
  unknown
> = z.object({
  ignoreCase: types.optional(types.boolean()),
});

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

/** @internal */
export const SegmentLhs2$inboundSchema: z.ZodType<
  SegmentLhs2,
  z.ZodTypeDef,
  unknown
> = z.object({
  type: types.literal("entity"),
  kind: types.string(),
  attribute: types.string(),
});

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

/** @internal */
export const SegmentLhs1$inboundSchema: z.ZodType<
  SegmentLhs1,
  z.ZodTypeDef,
  unknown
> = z.object({
  type: types.literal("segment"),
});

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

/** @internal */
export const SegmentLhs$inboundSchema: z.ZodType<
  SegmentLhs,
  z.ZodTypeDef,
  unknown
> = z.union([
  z.lazy(() => SegmentLhs1$inboundSchema),
  z.lazy(() => SegmentLhs2$inboundSchema),
]);

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

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

/** @internal */
export const SegmentConditions$inboundSchema: z.ZodType<
  SegmentConditions,
  z.ZodTypeDef,
  unknown
> = z.object({
  rhs: types.optional(
    smartUnion([
      z.lazy(() => SegmentRhs4$inboundSchema),
      z.lazy(() => SegmentRhs3$inboundSchema),
      types.string(),
      types.number(),
      types.boolean(),
    ]),
  ),
  cmpOptions: types.optional(z.lazy(() => SegmentCmpOptions$inboundSchema)),
  lhs: z.union([
    z.lazy(() => SegmentLhs1$inboundSchema),
    z.lazy(() => SegmentLhs2$inboundSchema),
  ]),
  cmp: SegmentCmp$inboundSchema,
});

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

/** @internal */
export const SegmentRules$inboundSchema: z.ZodType<
  SegmentRules,
  z.ZodTypeDef,
  unknown
> = z.object({
  id: types.string(),
  outcome: z.union([
    z.lazy(() => SegmentOutcome1$inboundSchema),
    z.lazy(() => SegmentOutcome2$inboundSchema),
  ]),
  conditions: z.array(z.lazy(() => SegmentConditions$inboundSchema)),
});

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

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

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

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

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

/** @internal */
export const Data$inboundSchema: z.ZodType<Data, z.ZodTypeDef, unknown> = z
  .object({
    rules: types.optional(z.array(z.lazy(() => SegmentRules$inboundSchema))),
    include: types.optional(
      z.record(z.record(z.array(z.lazy(() => Include$inboundSchema)))),
    ),
    exclude: types.optional(
      z.record(z.record(z.array(z.lazy(() => ExcludeT$inboundSchema)))),
    ),
  });

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

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

/** @internal */
export const SegmentCreator$inboundSchema: z.ZodType<
  SegmentCreator,
  z.ZodTypeDef,
  unknown
> = z.object({
  id: types.string(),
  name: types.string(),
});

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

/** @internal */
export const SegmentMetadata$inboundSchema: z.ZodType<
  SegmentMetadata,
  z.ZodTypeDef,
  unknown
> = z.object({
  creator: types.optional(z.lazy(() => SegmentCreator$inboundSchema)),
});

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

/** @internal */
export const Segment$inboundSchema: z.ZodType<Segment, z.ZodTypeDef, unknown> =
  z.object({
    description: types.optional(types.string()),
    createdBy: types.optional(types.string()),
    usedByFlags: types.optional(z.array(types.string())),
    usedBySegments: types.optional(z.array(types.string())),
    data: z.lazy(() => Data$inboundSchema),
    id: types.string(),
    label: types.string(),
    slug: types.string(),
    createdAt: types.number(),
    updatedAt: types.number(),
    projectId: types.string(),
    typeName: SegmentTypeName$inboundSchema,
    hint: types.string(),
    metadata: types.optional(z.lazy(() => SegmentMetadata$inboundSchema)),
  });

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