// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.29.0
// source: mq.sql

package sqlcv1

import (
	"context"

	"github.com/google/uuid"
	"github.com/jackc/pgx/v5/pgtype"
)

const addMessage = `-- name: AddMessage :exec
INSERT INTO
    "MessageQueueItem" (
        "payload",
        "queueId",
        "readAfter",
        "expiresAt"
    )
VALUES
    (
        $1::jsonb,
        $2::text,
        NOW(),
        NOW() + INTERVAL '5 minutes'
    )
`

type AddMessageParams struct {
	Payload []byte `json:"payload"`
	Queueid string `json:"queueid"`
}

func (q *Queries) AddMessage(ctx context.Context, db DBTX, arg AddMessageParams) error {
	_, err := db.Exec(ctx, addMessage, arg.Payload, arg.Queueid)
	return err
}

const bulkAckMessages = `-- name: BulkAckMessages :exec
DELETE FROM
    "MessageQueueItem"
WHERE
    "id" = ANY($1::bigint[])
    AND "status" = 'ASSIGNED'
`

func (q *Queries) BulkAckMessages(ctx context.Context, db DBTX, ids []int64) error {
	_, err := db.Exec(ctx, bulkAckMessages, ids)
	return err
}

type BulkAddMessageParams struct {
	Payload   []byte           `json:"payload"`
	QueueId   pgtype.Text      `json:"queueId"`
	ReadAfter pgtype.Timestamp `json:"readAfter"`
	ExpiresAt pgtype.Timestamp `json:"expiresAt"`
}

const cleanupMessageQueue = `-- name: CleanupMessageQueue :exec
DELETE FROM
    "MessageQueue"
WHERE
    "lastActive" < NOW() - INTERVAL '1 hour'
    AND "autoDeleted" = true
`

func (q *Queries) CleanupMessageQueue(ctx context.Context, db DBTX) error {
	_, err := db.Exec(ctx, cleanupMessageQueue)
	return err
}

const cleanupMessageQueueItems = `-- name: CleanupMessageQueueItems :exec
DELETE FROM "MessageQueueItem"
WHERE "expiresAt" < NOW()
AND
    "id" >= $1::bigint
    AND "id" <= $2::bigint
`

type CleanupMessageQueueItemsParams struct {
	Minid int64 `json:"minid"`
	Maxid int64 `json:"maxid"`
}

func (q *Queries) CleanupMessageQueueItems(ctx context.Context, db DBTX, arg CleanupMessageQueueItemsParams) error {
	_, err := db.Exec(ctx, cleanupMessageQueueItems, arg.Minid, arg.Maxid)
	return err
}

const deleteExpiredMessages = `-- name: DeleteExpiredMessages :exec
DELETE FROM
    "MessageQueueItem"
WHERE
    "expiresAt" < NOW()
`

func (q *Queries) DeleteExpiredMessages(ctx context.Context, db DBTX) error {
	_, err := db.Exec(ctx, deleteExpiredMessages)
	return err
}

const getMinMaxExpiredMessageQueueItems = `-- name: GetMinMaxExpiredMessageQueueItems :one
SELECT
    COALESCE(MIN("id"), 0)::bigint AS "minId",
    COALESCE(MAX("id"), 0)::bigint AS "maxId"
FROM
    "MessageQueueItem"
WHERE
    "expiresAt" < NOW()
`

type GetMinMaxExpiredMessageQueueItemsRow struct {
	MinId int64 `json:"minId"`
	MaxId int64 `json:"maxId"`
}

func (q *Queries) GetMinMaxExpiredMessageQueueItems(ctx context.Context, db DBTX) (*GetMinMaxExpiredMessageQueueItemsRow, error) {
	row := db.QueryRow(ctx, getMinMaxExpiredMessageQueueItems)
	var i GetMinMaxExpiredMessageQueueItemsRow
	err := row.Scan(&i.MinId, &i.MaxId)
	return &i, err
}

const readMessages = `-- name: ReadMessages :many
WITH messages AS (
    SELECT
        id, payload, "readAfter", "expiresAt", "queueId", status
    FROM
        "MessageQueueItem"
    WHERE
        "expiresAt" > NOW()
        AND "queueId" = $1::text
        AND "readAfter" <= NOW()
        AND "status" = 'PENDING'
    ORDER BY
        "id" ASC
    LIMIT
        COALESCE($2::integer, 1000)
    FOR UPDATE SKIP LOCKED
)
UPDATE
    "MessageQueueItem"
SET
    "status" = 'ASSIGNED'
FROM
    messages
WHERE
    "MessageQueueItem"."id" = messages."id"
RETURNING messages.id, messages.payload, messages."readAfter", messages."expiresAt", messages."queueId", messages.status
`

type ReadMessagesParams struct {
	Queueid string      `json:"queueid"`
	Limit   pgtype.Int4 `json:"limit"`
}

type ReadMessagesRow struct {
	ID        int64                  `json:"id"`
	Payload   []byte                 `json:"payload"`
	ReadAfter pgtype.Timestamp       `json:"readAfter"`
	ExpiresAt pgtype.Timestamp       `json:"expiresAt"`
	QueueId   pgtype.Text            `json:"queueId"`
	Status    MessageQueueItemStatus `json:"status"`
}

func (q *Queries) ReadMessages(ctx context.Context, db DBTX, arg ReadMessagesParams) ([]*ReadMessagesRow, error) {
	rows, err := db.Query(ctx, readMessages, arg.Queueid, arg.Limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ReadMessagesRow
	for rows.Next() {
		var i ReadMessagesRow
		if err := rows.Scan(
			&i.ID,
			&i.Payload,
			&i.ReadAfter,
			&i.ExpiresAt,
			&i.QueueId,
			&i.Status,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const updateMessageQueueActive = `-- name: UpdateMessageQueueActive :exec
UPDATE
    "MessageQueue"
SET
    "lastActive" = NOW()
WHERE
    "name" = $1::text
`

func (q *Queries) UpdateMessageQueueActive(ctx context.Context, db DBTX, name string) error {
	_, err := db.Exec(ctx, updateMessageQueueActive, name)
	return err
}

const upsertMessageQueue = `-- name: UpsertMessageQueue :one
INSERT INTO
    "MessageQueue" (
        "name",
        "durable",
        "autoDeleted",
        "exclusive",
        "exclusiveConsumerId"
    )
VALUES (
    $1::text,
    $2::boolean,
    $3::boolean,
    $4::boolean,
    CASE WHEN $5::uuid IS NOT NULL THEN $5::uuid ELSE NULL END
) ON CONFLICT ("name") DO UPDATE
SET
    "durable" = $2::boolean,
    "autoDeleted" = $3::boolean,
    "exclusive" = $4::boolean,
    "exclusiveConsumerId" = CASE WHEN $5::uuid IS NOT NULL THEN $5::uuid ELSE NULL END
RETURNING name, "lastActive", durable, "autoDeleted", exclusive, "exclusiveConsumerId"
`

type UpsertMessageQueueParams struct {
	Name                string     `json:"name"`
	Durable             bool       `json:"durable"`
	Autodeleted         bool       `json:"autodeleted"`
	Exclusive           bool       `json:"exclusive"`
	ExclusiveConsumerId *uuid.UUID `json:"exclusiveConsumerId"`
}

func (q *Queries) UpsertMessageQueue(ctx context.Context, db DBTX, arg UpsertMessageQueueParams) (*MessageQueue, error) {
	row := db.QueryRow(ctx, upsertMessageQueue,
		arg.Name,
		arg.Durable,
		arg.Autodeleted,
		arg.Exclusive,
		arg.ExclusiveConsumerId,
	)
	var i MessageQueue
	err := row.Scan(
		&i.Name,
		&i.LastActive,
		&i.Durable,
		&i.AutoDeleted,
		&i.Exclusive,
		&i.ExclusiveConsumerId,
	)
	return &i, err
}
