// this file is @generated

import { type BulkReplayIn, BulkReplayInSerializer } from "../models/bulkReplayIn";
import {
  type EndpointHeadersIn,
  EndpointHeadersInSerializer,
} from "../models/endpointHeadersIn";
import {
  type EndpointHeadersOut,
  EndpointHeadersOutSerializer,
} from "../models/endpointHeadersOut";
import {
  type EndpointHeadersPatchIn,
  EndpointHeadersPatchInSerializer,
} from "../models/endpointHeadersPatchIn";
import { type EndpointIn, EndpointInSerializer } from "../models/endpointIn";
import { type EndpointOut, EndpointOutSerializer } from "../models/endpointOut";
import { type EndpointPatch, EndpointPatchSerializer } from "../models/endpointPatch";
import {
  type EndpointSecretOut,
  EndpointSecretOutSerializer,
} from "../models/endpointSecretOut";
import {
  type EndpointSecretRotateIn,
  EndpointSecretRotateInSerializer,
} from "../models/endpointSecretRotateIn";
import { type EndpointStats, EndpointStatsSerializer } from "../models/endpointStats";
import {
  type EndpointTransformationIn,
  EndpointTransformationInSerializer,
} from "../models/endpointTransformationIn";
import {
  type EndpointUpsertIn,
  EndpointUpsertInSerializer,
} from "../models/endpointUpsertIn";
import { type EventExampleIn, EventExampleInSerializer } from "../models/eventExampleIn";
import {
  type ListResponseEndpointOut,
  ListResponseEndpointOutSerializer,
} from "../models/listResponseEndpointOut";
import { type MessageOut, MessageOutSerializer } from "../models/messageOut";
import type { Ordering } from "../models/ordering";
import { type RecoverIn, RecoverInSerializer } from "../models/recoverIn";
import { type RecoverOut, RecoverOutSerializer } from "../models/recoverOut";
import { type ReplayIn, ReplayInSerializer } from "../models/replayIn";
import { type ReplayOut, ReplayOutSerializer } from "../models/replayOut";
import { EndpointTransformation } from "./endpointTransformation";
import { HttpMethod, SvixRequest, type SvixRequestContext } from "../request";

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

export interface EndpointCreateOptions {
  idempotencyKey?: string;
}

export interface EndpointRotateSecretOptions {
  idempotencyKey?: string;
}

export interface EndpointReplayMissingOptions {
  idempotencyKey?: string;
}

export interface EndpointBulkReplayOptions {
  idempotencyKey?: string;
}

export interface EndpointGetStatsOptions {
  /** Filter the range to data starting from this date. */
  since?: Date | null;
  /** Filter the range to data ending by this date. */
  until?: Date | null;
}

export interface EndpointRecoverOptions {
  idempotencyKey?: string;
}

export interface EndpointSendExampleOptions {
  idempotencyKey?: string;
}

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

  public get transformation() {
    return new EndpointTransformation(this.requestCtx);
  }

  /** List the application's endpoints. */
  public async list(
    appId: string,
    options?: EndpointListOptions
  ): Promise<ListResponseEndpointOut> {
    const request = new SvixRequest(HttpMethod.GET, "/api/v1/app/{app_id}/endpoint");

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

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

  /**
   * Create a new endpoint for the application.
   *
   * When `secret` is `null` the secret is automatically generated (recommended).
   */
  public async create(
    appId: string,
    endpointIn: EndpointIn,
    options?: EndpointCreateOptions
  ): Promise<EndpointOut> {
    const request = new SvixRequest(HttpMethod.POST, "/api/v1/app/{app_id}/endpoint");

    request.setPathParam("app_id", appId);
    request.setHeaderParam("idempotency-key", options?.idempotencyKey);
    request.setBody(EndpointInSerializer._toJsonObject(endpointIn));

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

  /** Get an endpoint. */
  public async get(appId: string, endpointId: string): Promise<EndpointOut> {
    const request = new SvixRequest(
      HttpMethod.GET,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);

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

  /** Create or update an endpoint. */
  public async upsert(
    appId: string,
    endpointId: string,
    endpointUpsertIn: EndpointUpsertIn
  ): Promise<EndpointOut> {
    const request = new SvixRequest(
      HttpMethod.PUT,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setBody(EndpointUpsertInSerializer._toJsonObject(endpointUpsertIn));

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

  /** Delete an endpoint. */
  public async delete(appId: string, endpointId: string): Promise<void> {
    const request = new SvixRequest(
      HttpMethod.DELETE,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);

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

  /** Partially update an endpoint. */
  public async patch(
    appId: string,
    endpointId: string,
    endpointPatch: EndpointPatch
  ): Promise<EndpointOut> {
    const request = new SvixRequest(
      HttpMethod.PATCH,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setBody(EndpointPatchSerializer._toJsonObject(endpointPatch));

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

  /**
   * Get the endpoint's signing secret.
   *
   * This is used to verify the authenticity of the webhook.
   * For more information please refer to [the consuming webhooks docs](https://docs.svix.com/consuming-webhooks/).
   */
  public async getSecret(appId: string, endpointId: string): Promise<EndpointSecretOut> {
    const request = new SvixRequest(
      HttpMethod.GET,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/secret"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);

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

  /**
   * Rotates the endpoint's signing secret.
   *
   * The previous secret will remain valid for the specified grace period (default 24 hours).
   */
  public async rotateSecret(
    appId: string,
    endpointId: string,
    endpointSecretRotateIn: EndpointSecretRotateIn = {},
    options?: EndpointRotateSecretOptions
  ): Promise<void> {
    const request = new SvixRequest(
      HttpMethod.POST,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/secret/rotate"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setHeaderParam("idempotency-key", options?.idempotencyKey);
    request.setBody(
      EndpointSecretRotateInSerializer._toJsonObject(endpointSecretRotateIn)
    );

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

  /** Get the additional headers to be sent with the webhook. */
  public async getHeaders(
    appId: string,
    endpointId: string
  ): Promise<EndpointHeadersOut> {
    const request = new SvixRequest(
      HttpMethod.GET,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/headers"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);

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

  /** Set the additional headers to be sent with the webhook. */
  public async setHeaders(
    appId: string,
    endpointId: string,
    endpointHeadersIn: EndpointHeadersIn
  ): Promise<void> {
    const request = new SvixRequest(
      HttpMethod.PUT,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/headers"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setBody(EndpointHeadersInSerializer._toJsonObject(endpointHeadersIn));

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

  /** Partially set the additional headers to be sent with the webhook. */
  public async patchHeaders(
    appId: string,
    endpointId: string,
    endpointHeadersPatchIn: EndpointHeadersPatchIn
  ): Promise<void> {
    const request = new SvixRequest(
      HttpMethod.PATCH,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/headers"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setBody(
      EndpointHeadersPatchInSerializer._toJsonObject(endpointHeadersPatchIn)
    );

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

  /**
   * Replays messages to the endpoint.
   *
   * Only messages that were created after `since` will be sent.
   * Messages that were previously sent to the endpoint are not resent.
   *
   * A completed task will return a payload like the following:
   * ```json
   * {
   *   "id": "qtask_33qen93MNuelBAq1T9G7eHLJRsF",
   *   "status": "finished",
   *   "task": "endpoint.replay",
   *   "data": {
   *     "messagesSent": 2
   *   }
   * }
   * ```
   */
  public async replayMissing(
    appId: string,
    endpointId: string,
    replayIn: ReplayIn,
    options?: EndpointReplayMissingOptions
  ): Promise<ReplayOut> {
    const request = new SvixRequest(
      HttpMethod.POST,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/replay-missing"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setHeaderParam("idempotency-key", options?.idempotencyKey);
    request.setBody(ReplayInSerializer._toJsonObject(replayIn));

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

  /**
   * Bulk replay messages sent to the endpoint.
   *
   * Only messages that were created after `since` will be sent.
   * This will replay both successful, and failed messages
   *
   * A completed task will return a payload like the following:
   * ```json
   * {
   *   "id": "qtask_33qen93MNuelBAq1T9G7eHLJRsF",
   *   "status": "finished",
   *   "task": "endpoint.bulk-replay",
   *   "data": {
   *     "messagesSent": 2
   *   }
   * }
   * ```
   */
  public async bulkReplay(
    appId: string,
    endpointId: string,
    bulkReplayIn: BulkReplayIn,
    options?: EndpointBulkReplayOptions
  ): Promise<ReplayOut> {
    const request = new SvixRequest(
      HttpMethod.POST,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/bulk-replay"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setHeaderParam("idempotency-key", options?.idempotencyKey);
    request.setBody(BulkReplayInSerializer._toJsonObject(bulkReplayIn));

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

  /** Get basic statistics for the endpoint. */
  public async getStats(
    appId: string,
    endpointId: string,
    options?: EndpointGetStatsOptions
  ): Promise<EndpointStats> {
    const request = new SvixRequest(
      HttpMethod.GET,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/stats"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setQueryParams({
      since: options?.since,
      until: options?.until,
    });

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

  /**
   * Resend all failed messages since a given time.
   *
   * Messages that were sent successfully, even if failed initially, are not resent.
   *
   * A completed task will return a payload like the following:
   * ```json
   * {
   *   "id": "qtask_33qen93MNuelBAq1T9G7eHLJRsF",
   *   "status": "finished",
   *   "task": "endpoint.recover",
   *   "data": {
   *     "messagesSent": 2
   *   }
   * }
   * ```
   */
  public async recover(
    appId: string,
    endpointId: string,
    recoverIn: RecoverIn,
    options?: EndpointRecoverOptions
  ): Promise<RecoverOut> {
    const request = new SvixRequest(
      HttpMethod.POST,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/recover"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setHeaderParam("idempotency-key", options?.idempotencyKey);
    request.setBody(RecoverInSerializer._toJsonObject(recoverIn));

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

  /** Send an example message for an event. */
  public async sendExample(
    appId: string,
    endpointId: string,
    eventExampleIn: EventExampleIn,
    options?: EndpointSendExampleOptions
  ): Promise<MessageOut> {
    const request = new SvixRequest(
      HttpMethod.POST,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/send-example"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setHeaderParam("idempotency-key", options?.idempotencyKey);
    request.setBody(EventExampleInSerializer._toJsonObject(eventExampleIn));

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

  /**
   * This operation was renamed to `set-transformation`.
   *
   * @deprecated
   */
  public async transformationPartialUpdate(
    appId: string,
    endpointId: string,
    endpointTransformationIn: EndpointTransformationIn = {}
  ): Promise<void> {
    const request = new SvixRequest(
      HttpMethod.PATCH,
      "/api/v1/app/{app_id}/endpoint/{endpoint_id}/transformation"
    );

    request.setPathParam("app_id", appId);
    request.setPathParam("endpoint_id", endpointId);
    request.setBody(
      EndpointTransformationInSerializer._toJsonObject(endpointTransformationIn)
    );

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