// this file is @generated

import { type EmptyResponse, EmptyResponseSerializer } from "../models/emptyResponse";
import {
  type ListResponseEndpointMessageOut,
  ListResponseEndpointMessageOutSerializer,
} from "../models/listResponseEndpointMessageOut";
import {
  type ListResponseMessageAttemptOut,
  ListResponseMessageAttemptOutSerializer,
} from "../models/listResponseMessageAttemptOut";
import {
  type ListResponseMessageEndpointOut,
  ListResponseMessageEndpointOutSerializer,
} from "../models/listResponseMessageEndpointOut";
import {
  type MessageAttemptOut,
  MessageAttemptOutSerializer,
} from "../models/messageAttemptOut";
import type { MessageStatus } from "../models/messageStatus";
import type { StatusCodeClass } from "../models/statusCodeClass";
import { HttpMethod, SvixRequest, type SvixRequestContext } from "../request";

export interface MessageAttemptListByEndpointOptions {
  /** Limit the number of returned items */
  limit?: number;
  /** The iterator returned from a prior invocation */
  iterator?: string | null;
  /** Filter response based on the status of the attempt: Success (0), Pending (1), Failed (2), Sending (3), or Canceled (4) */
  status?: MessageStatus;
  /** Filter response based on the HTTP status code */
  statusCodeClass?: StatusCodeClass;
  /** Filter response based on the channel */
  channel?: string;
  /** Filter response based on the tag */
  tag?: string;
  /** Only include items created before a certain date */
  before?: Date | null;
  /** Only include items created after a certain date */
  after?: Date | null;
  /**
   * When `true` attempt content is included in the response.
   *
   * Defaults to `false` in v2+ of the Svix SDKs, `true` in v1 or when manually making a request without specifying this parameter.
   */
  withContent?: boolean;
  /**
   * When `true`, the message information is included in the response
   *
   * Note that message payloads are never included in the response, regardless of this flag.
   */
  withMsg?: boolean;
  /**
   * When `true`, return the Canceled (4) status in attempts.
   *
   * If `false`, canceled attempts are returned as Success (0) for backwards compatibility.
   */
  expandedStatuses?: boolean;
  /** Filter response based on the event type */
  eventTypes?: string[];
}

export interface MessageAttemptListByMsgOptions {
  /** Limit the number of returned items */
  limit?: number;
  /** The iterator returned from a prior invocation */
  iterator?: string | null;
  /** Filter response based on the status of the attempt: Success (0), Pending (1), Failed (2), Sending (3), or Canceled (4) */
  status?: MessageStatus;
  /** Filter response based on the HTTP status code */
  statusCodeClass?: StatusCodeClass;
  /** Filter response based on the channel */
  channel?: string;
  /** Filter response based on the tag */
  tag?: string;
  /** Filter the attempts based on the attempted endpoint */
  endpointId?: string;
  /** Only include items created before a certain date */
  before?: Date | null;
  /** Only include items created after a certain date */
  after?: Date | null;
  /**
   * When `true` attempt content is included in the response.
   *
   * Defaults to `false` in v2+ of the Svix SDKs, `true` in v1 or when manually making a request without specifying this parameter.
   */
  withContent?: boolean;
  /**
   * When `true`, return the Canceled (4) status in attempts.
   *
   * If `false`, canceled attempts are returned as Success (0) for backwards compatibility.
   */
  expandedStatuses?: boolean;
  /** Filter response based on the event type */
  eventTypes?: string[];
}

export interface MessageAttemptListAttemptedMessagesOptions {
  /** Limit the number of returned items */
  limit?: number;
  /** The iterator returned from a prior invocation */
  iterator?: string | null;
  /** Filter response based on the channel */
  channel?: string;
  /** Filter response based on the message tags */
  tag?: string;
  /** Filter response based on the status of the attempt: Success (0), Pending (1), Failed (2), Sending (3), or Canceled (4) */
  status?: MessageStatus;
  /** Only include items created before a certain date */
  before?: Date | null;
  /** Only include items created after a certain date */
  after?: Date | null;
  /**
   * When `true` message payloads are included in the response.
   *
   * Defaults to `false` in v2+ of the Svix SDKs, `true` in v1 or when manually making a request without specifying this parameter.
   */
  withContent?: boolean;
  /**
   * When `true`, return the Canceled (4) status in attempts.
   *
   * If `false`, canceled attempts are returned as Success (0) for backwards compatibility.
   */
  expandedStatuses?: boolean;
  /** Filter response based on the event type */
  eventTypes?: string[];
}

export interface MessageAttemptListAttemptedDestinationsOptions {
  /** Limit the number of returned items */
  limit?: number;
  /** The iterator returned from a prior invocation */
  iterator?: string | null;
}

export interface MessageAttemptGetOptions {
  /**
   * When `true`, return the Canceled (4) status in attempts.
   *
   * If `false`, canceled attempts are returned as Success (0) for backwards compatibility.
   */
  expandedStatuses?: boolean;
}

export interface MessageAttemptResendOptions {
  idempotencyKey?: string;
}

export class MessageAttempt {
  public constructor(private readonly requestCtx: SvixRequestContext) {}

  /**
   * List attempts by endpoint id
   *
   * Note that by default this endpoint is limited to retrieving 90 days' worth of data
   * relative to now or, if an iterator is provided, 90 days before/after the time indicated
   * by the iterator ID. If you require data beyond those time ranges, you will need to explicitly
   * set the `before` or `after` parameter as appropriate.
   */
  public async listByEndpoint(
    appId: string,
    endpointId: string,
    options?: MessageAttemptListByEndpointOptions
  ): Promise<ListResponseMessageAttemptOut> {
    const request = new SvixRequest(
      HttpMethod.GET,
      "/api/v1/app/{app_id}/attempt/endpoint/{endpoint_id}"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setQueryParams({
      limit: options?.limit,
      iterator: options?.iterator,
      status: options?.status,
      status_code_class: options?.statusCodeClass,
      channel: options?.channel,
      tag: options?.tag,
      before: options?.before,
      after: options?.after,
      with_content: options?.withContent ?? false,
      with_msg: options?.withMsg,
      expanded_statuses: options?.expandedStatuses ?? true,
      event_types: options?.eventTypes,
    });

    return await request.send(
      this.requestCtx,
      ListResponseMessageAttemptOutSerializer._fromJsonObject
    );
  }

  /**
   * List attempts by message ID.
   *
   * Note that by default this endpoint is limited to retrieving 90 days' worth of data
   * relative to now or, if an iterator is provided, 90 days before/after the time indicated
   * by the iterator ID. If you require data beyond those time ranges, you will need to explicitly
   * set the `before` or `after` parameter as appropriate.
   */
  public async listByMsg(
    appId: string,
    msgId: string,
    options?: MessageAttemptListByMsgOptions
  ): Promise<ListResponseMessageAttemptOut> {
    const request = new SvixRequest(
      HttpMethod.GET,
      "/api/v1/app/{app_id}/attempt/msg/{msg_id}"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("msg_id", msgId);
    request.setQueryParams({
      limit: options?.limit,
      iterator: options?.iterator,
      status: options?.status,
      status_code_class: options?.statusCodeClass,
      channel: options?.channel,
      tag: options?.tag,
      endpoint_id: options?.endpointId,
      before: options?.before,
      after: options?.after,
      with_content: options?.withContent ?? false,
      expanded_statuses: options?.expandedStatuses ?? true,
      event_types: options?.eventTypes,
    });

    return await request.send(
      this.requestCtx,
      ListResponseMessageAttemptOutSerializer._fromJsonObject
    );
  }

  /**
   * List messages for a particular endpoint.
   *
   * Additionally includes metadata about the latest message attempt.
   * The `before` parameter lets you filter all items created before a certain date and is ignored if an iterator is passed.
   *
   * Note that by default this endpoint is limited to retrieving 90 days' worth of data
   * relative to now or, if an iterator is provided, 90 days before/after the time indicated
   * by the iterator ID. If you require data beyond those time ranges, you will need to explicitly
   * set the `before` or `after` parameter as appropriate.
   */
  public async listAttemptedMessages(
    appId: string,
    endpointId: string,
    options?: MessageAttemptListAttemptedMessagesOptions
  ): Promise<ListResponseEndpointMessageOut> {
    const request = new SvixRequest(
      HttpMethod.GET,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/msg"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setQueryParams({
      limit: options?.limit,
      iterator: options?.iterator,
      channel: options?.channel,
      tag: options?.tag,
      status: options?.status,
      before: options?.before,
      after: options?.after,
      with_content: options?.withContent ?? false,
      expanded_statuses: options?.expandedStatuses ?? true,
      event_types: options?.eventTypes,
    });

    return await request.send(
      this.requestCtx,
      ListResponseEndpointMessageOutSerializer._fromJsonObject
    );
  }

  /**
   * List endpoints attempted by a given message.
   *
   * Additionally includes metadata about the latest message attempt.
   * By default, endpoints are listed in ascending order by ID.
   */
  public async listAttemptedDestinations(
    appId: string,
    msgId: string,
    options?: MessageAttemptListAttemptedDestinationsOptions
  ): Promise<ListResponseMessageEndpointOut> {
    const request = new SvixRequest(
      HttpMethod.GET,
      "/api/v1/app/{app_id}/msg/{msg_id}/endpoint"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("msg_id", msgId);
    request.setQueryParams({
      limit: options?.limit,
      iterator: options?.iterator,
    });

    return await request.send(
      this.requestCtx,
      ListResponseMessageEndpointOutSerializer._fromJsonObject
    );
  }

  /** `msg_id`: Use a message id or a message `eventId` */
  public async get(
    appId: string,
    msgId: string,
    attemptId: string,
    options?: MessageAttemptGetOptions
  ): Promise<MessageAttemptOut> {
    const request = new SvixRequest(
      HttpMethod.GET,
      "/api/v1/app/{app_id}/msg/{msg_id}/attempt/{attempt_id}"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("msg_id", msgId);
    request.setPathParam("attempt_id", attemptId);
    request.setQueryParams({
      expanded_statuses: options?.expandedStatuses ?? true,
    });

    return await request.send(
      this.requestCtx,
      MessageAttemptOutSerializer._fromJsonObject
    );
  }

  /**
   * Deletes the given attempt's response body.
   *
   * Useful when an endpoint accidentally returned sensitive content.
   * The message can't be replayed or resent once its payload has been deleted or expired.
   */
  public async expungeContent(
    appId: string,
    msgId: string,
    attemptId: string
  ): Promise<void> {
    const request = new SvixRequest(
      HttpMethod.DELETE,
      "/api/v1/app/{app_id}/msg/{msg_id}/attempt/{attempt_id}/content"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("msg_id", msgId);
    request.setPathParam("attempt_id", attemptId);

    return await request.sendNoResponseBody(this.requestCtx);
  }

  /** Resend a message to the specified endpoint. */
  public async resend(
    appId: string,
    msgId: string,
    endpointId: string,
    options?: MessageAttemptResendOptions
  ): Promise<EmptyResponse> {
    const request = new SvixRequest(
      HttpMethod.POST,
      "/api/v1/app/{app_id}/msg/{msg_id}/endpoint/{endpoint_id}/resend"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("msg_id", msgId);
    request.setPathParam("endpoint_id", endpointId);
    request.setHeaderParam("idempotency-key", options?.idempotencyKey);

    return await request.send(this.requestCtx, EmptyResponseSerializer._fromJsonObject);
  }
}
