/*
 * 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 { SDKValidationError } from "../errors/sdkvalidationerror.js";
import {
  DenominatorPost,
  DenominatorPost$inboundSchema,
  DenominatorPost$Outbound,
  DenominatorPost$outboundSchema,
} from "./denominatorpost.js";
import {
  EventFilter,
  EventFilter$inboundSchema,
  EventFilter$Outbound,
  EventFilter$outboundSchema,
} from "./eventfilter.js";
import {
  MetricDataSourceRefRep,
  MetricDataSourceRefRep$inboundSchema,
  MetricDataSourceRefRep$Outbound,
  MetricDataSourceRefRep$outboundSchema,
} from "./metricdatasourcerefrep.js";
import {
  MetricEventDefaultRep,
  MetricEventDefaultRep$inboundSchema,
  MetricEventDefaultRep$Outbound,
  MetricEventDefaultRep$outboundSchema,
} from "./metriceventdefaultrep.js";
import {
  UrlPost,
  UrlPost$inboundSchema,
  UrlPost$Outbound,
  UrlPost$outboundSchema,
} from "./urlpost.js";

/**
 * The kind of event your metric will track
 */
export const MetricPostKind = {
  Pageview: "pageview",
  Click: "click",
  Custom: "custom",
  Trace: "trace",
} as const;
/**
 * The kind of event your metric will track
 */
export type MetricPostKind = ClosedEnum<typeof MetricPostKind>;

/**
 * Success criteria. Required for custom and trace numeric metrics, optional for custom and trace conversion metrics.
 */
export const MetricPostSuccessCriteria = {
  HigherThanBaseline: "HigherThanBaseline",
  LowerThanBaseline: "LowerThanBaseline",
} as const;
/**
 * Success criteria. Required for custom and trace numeric metrics, optional for custom and trace conversion metrics.
 */
export type MetricPostSuccessCriteria = ClosedEnum<
  typeof MetricPostSuccessCriteria
>;

/**
 * The method by which multiple unit event values are aggregated
 */
export const MetricPostUnitAggregationType = {
  Average: "average",
  Sum: "sum",
  CountDistinct: "count_distinct",
} as const;
/**
 * The method by which multiple unit event values are aggregated
 */
export type MetricPostUnitAggregationType = ClosedEnum<
  typeof MetricPostUnitAggregationType
>;

export type MetricPost = {
  /**
   * A unique key to reference the metric
   */
  key: string;
  /**
   * A human-friendly name for the metric
   */
  name?: string | undefined;
  /**
   * Description of the metric
   */
  description?: string | undefined;
  /**
   * The kind of event your metric will track
   */
  kind: MetricPostKind;
  /**
   * One or more CSS selectors. Required for click metrics only.
   */
  selector?: string | undefined;
  /**
   * One or more target URLs. Required for click and pageview metrics only.
   */
  urls?: Array<UrlPost> | undefined;
  /**
   * Whether to track numeric changes in value against a baseline (<code>true</code>) or to track a conversion when an end user takes an action (<code>false</code>). Required for custom and trace metrics only.
   */
  isNumeric?: boolean | undefined;
  /**
   * The unit of measure. Applicable for numeric custom and trace metrics only.
   */
  unit?: string | undefined;
  /**
   * The event key to use in your code. Required for custom conversion/binary and custom numeric metrics only.
   */
  eventKey?: string | undefined;
  /**
   * Success criteria. Required for custom and trace numeric metrics, optional for custom and trace conversion metrics.
   */
  successCriteria?: MetricPostSuccessCriteria | undefined;
  /**
   * Tags for the metric
   */
  tags?: Array<string> | undefined;
  /**
   * Deprecated, use <code>analysisUnits</code> instead.
   *
   * @deprecated field: This will be removed in a future release, please migrate away from it as soon as possible.
   */
  randomizationUnits?: Array<string> | undefined;
  /**
   * An array of analysis units allowed for this metric.
   */
  analysisUnits?: Array<string> | undefined;
  /**
   * The ID of the member who maintains this metric
   */
  maintainerId?: string | undefined;
  /**
   * The method by which multiple unit event values are aggregated
   */
  unitAggregationType?: MetricPostUnitAggregationType | undefined;
  /**
   * The method for analyzing metric events
   */
  analysisType?: string | undefined;
  /**
   * The percentile for the analysis method. An integer denoting the target percentile between 0 and 100. Required when <code>analysisType</code> is <code>percentile</code>.
   */
  percentileValue?: number | undefined;
  eventDefault?: MetricEventDefaultRep | undefined;
  dataSource?: MetricDataSourceRefRep | undefined;
  filters?: EventFilter | undefined;
  /**
   * Not yet implemented - The start of the measurement window, in milliseconds relative to the unit's first exposure to a flag variation
   */
  windowStartOffset?: number | undefined;
  /**
   * Not yet implemented - The end of the measurement window, in milliseconds relative to the unit's first exposure to a flag variation
   */
  windowEndOffset?: number | undefined;
  /**
   * Lower winsorization percentile, expressed as a percent in the open interval (0, 100). When both bounds are set, defines a two-sided clamp range. Otherwise lower-only winsorization.
   */
  winsorLowerPercentile?: number | undefined;
  /**
   * Upper winsorization percentile, expressed as a percent in the open interval (0, 100). When both bounds are set, must be greater than winsorLowerPercentile.
   */
  winsorUpperPercentile?: number | undefined;
  /**
   * When true, the percentile bound calculation includes imputed zeros. Only meaningful when at least one bound is set and the metric includes units that didn't send events.
   */
  winsorIncludeImputed?: boolean | undefined;
  /**
   * The trace query to use for the metric. Required for trace metrics.
   */
  traceQuery?: string | undefined;
  /**
   * The location in the trace to use for numeric values. Required for numeric trace metrics.
   */
  traceValueLocation?: string | undefined;
  /**
   * The warehouse column to use for counting distinct values. Required when the unitAggregationType is count_distinct.
   */
  unitAggregationField?: string | undefined;
  /**
   * For numeric warehouse-native metrics, the column holding the numeric value. Overrides the value column mapped on the data source.
   */
  valueColumn?: string | undefined;
  denominator?: DenominatorPost | undefined;
};

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

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

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

/** @internal */
export const MetricPost$inboundSchema: z.ZodType<
  MetricPost,
  z.ZodTypeDef,
  unknown
> = z.object({
  key: z.string(),
  name: z.string().optional(),
  description: z.string().optional(),
  kind: MetricPostKind$inboundSchema,
  selector: z.string().optional(),
  urls: z.array(UrlPost$inboundSchema).optional(),
  isNumeric: z.boolean().optional(),
  unit: z.string().optional(),
  eventKey: z.string().optional(),
  successCriteria: MetricPostSuccessCriteria$inboundSchema.optional(),
  tags: z.array(z.string()).optional(),
  randomizationUnits: z.array(z.string()).optional(),
  analysisUnits: z.array(z.string()).optional(),
  maintainerId: z.string().optional(),
  unitAggregationType: MetricPostUnitAggregationType$inboundSchema.optional(),
  analysisType: z.string().optional(),
  percentileValue: z.number().int().optional(),
  eventDefault: MetricEventDefaultRep$inboundSchema.optional(),
  dataSource: MetricDataSourceRefRep$inboundSchema.optional(),
  filters: EventFilter$inboundSchema.optional(),
  windowStartOffset: z.number().int().optional(),
  windowEndOffset: z.number().int().optional(),
  winsorLowerPercentile: z.number().optional(),
  winsorUpperPercentile: z.number().optional(),
  winsorIncludeImputed: z.boolean().optional(),
  traceQuery: z.string().optional(),
  traceValueLocation: z.string().optional(),
  unitAggregationField: z.string().optional(),
  valueColumn: z.string().optional(),
  denominator: DenominatorPost$inboundSchema.optional(),
});
/** @internal */
export type MetricPost$Outbound = {
  key: string;
  name?: string | undefined;
  description?: string | undefined;
  kind: string;
  selector?: string | undefined;
  urls?: Array<UrlPost$Outbound> | undefined;
  isNumeric?: boolean | undefined;
  unit?: string | undefined;
  eventKey?: string | undefined;
  successCriteria?: string | undefined;
  tags?: Array<string> | undefined;
  randomizationUnits?: Array<string> | undefined;
  analysisUnits?: Array<string> | undefined;
  maintainerId?: string | undefined;
  unitAggregationType?: string | undefined;
  analysisType?: string | undefined;
  percentileValue?: number | undefined;
  eventDefault?: MetricEventDefaultRep$Outbound | undefined;
  dataSource?: MetricDataSourceRefRep$Outbound | undefined;
  filters?: EventFilter$Outbound | undefined;
  windowStartOffset?: number | undefined;
  windowEndOffset?: number | undefined;
  winsorLowerPercentile?: number | undefined;
  winsorUpperPercentile?: number | undefined;
  winsorIncludeImputed?: boolean | undefined;
  traceQuery?: string | undefined;
  traceValueLocation?: string | undefined;
  unitAggregationField?: string | undefined;
  valueColumn?: string | undefined;
  denominator?: DenominatorPost$Outbound | undefined;
};

/** @internal */
export const MetricPost$outboundSchema: z.ZodType<
  MetricPost$Outbound,
  z.ZodTypeDef,
  MetricPost
> = z.object({
  key: z.string(),
  name: z.string().optional(),
  description: z.string().optional(),
  kind: MetricPostKind$outboundSchema,
  selector: z.string().optional(),
  urls: z.array(UrlPost$outboundSchema).optional(),
  isNumeric: z.boolean().optional(),
  unit: z.string().optional(),
  eventKey: z.string().optional(),
  successCriteria: MetricPostSuccessCriteria$outboundSchema.optional(),
  tags: z.array(z.string()).optional(),
  randomizationUnits: z.array(z.string()).optional(),
  analysisUnits: z.array(z.string()).optional(),
  maintainerId: z.string().optional(),
  unitAggregationType: MetricPostUnitAggregationType$outboundSchema.optional(),
  analysisType: z.string().optional(),
  percentileValue: z.number().int().optional(),
  eventDefault: MetricEventDefaultRep$outboundSchema.optional(),
  dataSource: MetricDataSourceRefRep$outboundSchema.optional(),
  filters: EventFilter$outboundSchema.optional(),
  windowStartOffset: z.number().int().optional(),
  windowEndOffset: z.number().int().optional(),
  winsorLowerPercentile: z.number().optional(),
  winsorUpperPercentile: z.number().optional(),
  winsorIncludeImputed: z.boolean().optional(),
  traceQuery: z.string().optional(),
  traceValueLocation: z.string().optional(),
  unitAggregationField: z.string().optional(),
  valueColumn: z.string().optional(),
  denominator: DenominatorPost$outboundSchema.optional(),
});

export function metricPostToJSON(metricPost: MetricPost): string {
  return JSON.stringify(MetricPost$outboundSchema.parse(metricPost));
}
export function metricPostFromJSON(
  jsonString: string,
): SafeParseResult<MetricPost, SDKValidationError> {
  return safeParse(
    jsonString,
    (x) => MetricPost$inboundSchema.parse(JSON.parse(x)),
    `Failed to parse 'MetricPost' from JSON`,
  );
}
