<?php

// this file is @generated
declare(strict_types=1);

namespace Svix\Api;

use Svix\Exception\ApiException;
use Svix\Models\EmptyResponse;
use Svix\Models\EndpointSecretRotateIn;
use Svix\Models\ListResponseStreamSinkOut;
use Svix\Models\SinkSecretOut;
use Svix\Models\StreamSinkIn;
use Svix\Models\StreamSinkOut;
use Svix\Models\StreamSinkPatch;
use Svix\Request\SvixHttpClient;

class StreamingSink
{
    public StreamingSinkTransformation $transformation;

    public function __construct(
        private readonly SvixHttpClient $client,
    ) {
        $this->transformation = new StreamingSinkTransformation($client);
    }

    /**
     * List of all the stream's sinks.
     *
     * @throws ApiException
     */
    public function list(
        string $streamId,
        StreamingSinkListOptions $options = new StreamingSinkListOptions(),
    ): ListResponseStreamSinkOut {
        $request = $this->client->newReq('GET', "/api/v1/stream/{$streamId}/sink");
        $request->setQueryParam('limit', $options->limit);
        $request->setQueryParam('iterator', $options->iterator);
        $request->setQueryParam('order', $options->order);
        $res = $this->client->send($request);

        return ListResponseStreamSinkOut::fromJson($res);
    }

    /**
     * Creates a new sink.
     *
     * @throws ApiException
     */
    public function create(
        string $streamId,
        StreamSinkIn $streamSinkIn,
        StreamingSinkCreateOptions $options = new StreamingSinkCreateOptions(),
    ): StreamSinkOut {
        $request = $this->client->newReq('POST', "/api/v1/stream/{$streamId}/sink");
        $request->setHeaderParam('idempotency-key', $options->idempotencyKey);
        $request->setBody(json_encode($streamSinkIn));
        $res = $this->client->send($request);

        return StreamSinkOut::fromJson($res);
    }

    /**
     * Get a sink by id or uid.
     *
     * @throws ApiException
     */
    public function get(
        string $streamId,
        string $sinkId,
    ): StreamSinkOut {
        $request = $this->client->newReq('GET', "/api/v1/stream/{$streamId}/sink/{$sinkId}");
        $res = $this->client->send($request);

        return StreamSinkOut::fromJson($res);
    }

    /**
     * Create or update a sink.
     *
     * @throws ApiException
     */
    public function upsert(
        string $streamId,
        string $sinkId,
        StreamSinkIn $streamSinkIn,
    ): StreamSinkOut {
        $request = $this->client->newReq('PUT', "/api/v1/stream/{$streamId}/sink/{$sinkId}");
        $request->setBody(json_encode($streamSinkIn));
        $res = $this->client->send($request);

        return StreamSinkOut::fromJson($res);
    }

    /**
     * Delete a sink.
     *
     * @throws ApiException
     */
    public function delete(
        string $streamId,
        string $sinkId,
    ): void {
        $request = $this->client->newReq('DELETE', "/api/v1/stream/{$streamId}/sink/{$sinkId}");
        $res = $this->client->sendNoResponseBody($request);
    }

    /**
     * Partially update a sink.
     *
     * @throws ApiException
     */
    public function patch(
        string $streamId,
        string $sinkId,
        StreamSinkPatch $streamSinkPatch,
    ): StreamSinkOut {
        $request = $this->client->newReq('PATCH', "/api/v1/stream/{$streamId}/sink/{$sinkId}");
        $request->setBody(json_encode($streamSinkPatch));
        $res = $this->client->send($request);

        return StreamSinkOut::fromJson($res);
    }

    /**
     * Get the sink's signing secret (only supported for http sinks).
     *
     * This is used to verify the authenticity of the delivery.
     *
     * For more information please refer to [the consuming webhooks docs](https://docs.svix.com/consuming-webhooks/).
     *
     * @throws ApiException
     */
    public function getSecret(
        string $streamId,
        string $sinkId,
    ): SinkSecretOut {
        $request = $this->client->newReq('GET', "/api/v1/stream/{$streamId}/sink/{$sinkId}/secret");
        $res = $this->client->send($request);

        return SinkSecretOut::fromJson($res);
    }

    /**
     * Rotates the signing secret (only supported for http sinks).
     *
     * @throws ApiException
     */
    public function rotateSecret(
        string $streamId,
        string $sinkId,
        EndpointSecretRotateIn $endpointSecretRotateIn,
        StreamingSinkRotateSecretOptions $options = new StreamingSinkRotateSecretOptions(),
    ): EmptyResponse {
        $request = $this->client->newReq('POST', "/api/v1/stream/{$streamId}/sink/{$sinkId}/secret/rotate");
        $request->setHeaderParam('idempotency-key', $options->idempotencyKey);
        $request->setBody(json_encode($endpointSecretRotateIn));
        $res = $this->client->send($request);

        return EmptyResponse::fromJson($res);
    }
}
