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

package sqlcv1

import (
	"context"

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

const cleanupOldWorkers = `-- name: CleanupOldWorkers :execresult
WITH old_workers AS (
    SELECT "id"
    FROM "Worker"
    WHERE "tenantId" = $1::uuid
      AND "lastHeartbeatAt" < $2::timestamp
    LIMIT $3::int
), deleted_worker_slot_configs AS (
    DELETE FROM v1_worker_slot_config
    WHERE worker_id IN (SELECT "id" FROM old_workers)
)
DELETE FROM "Worker"
WHERE "id" IN (SELECT "id" FROM old_workers)
`

type CleanupOldWorkersParams struct {
	Tenantid            uuid.UUID        `json:"tenantid"`
	Lastheartbeatbefore pgtype.Timestamp `json:"lastheartbeatbefore"`
	Batchsize           int32            `json:"batchsize"`
}

func (q *Queries) CleanupOldWorkers(ctx context.Context, db DBTX, arg CleanupOldWorkersParams) (pgconn.CommandTag, error) {
	return db.Exec(ctx, cleanupOldWorkers, arg.Tenantid, arg.Lastheartbeatbefore, arg.Batchsize)
}

const countWorkers = `-- name: CountWorkers :one
SELECT count(*)
FROM
    "Worker" workers
WHERE
    workers."tenantId" = $1
    AND (
        $2::text IS NULL OR
        workers."id" IN (
            SELECT "_ActionToWorker"."B"
            FROM "_ActionToWorker"
            INNER JOIN "Action" ON "Action"."id" = "_ActionToWorker"."A"
            WHERE "Action"."tenantId" = $1 AND "Action"."actionId" = $2::text
        )
    )
    AND (
        $3::timestamp IS NULL OR
        workers."lastHeartbeatAt" > $3::timestamp
    )
    AND (
        $4::boolean IS NULL OR
        ($4::boolean AND (
            SELECT COALESCE(SUM(cap.max_units), 0)
            FROM v1_worker_slot_config cap
            WHERE cap.tenant_id = workers."tenantId" AND cap.worker_id = workers."id"
        ) > (
            SELECT COALESCE(SUM(runtime.units), 0)
            FROM v1_task_runtime_slot runtime
            WHERE runtime.tenant_id = workers."tenantId" AND runtime.worker_id = workers."id"
        ))
    )
    AND (
        $5::text[] IS NULL OR
        CASE
            WHEN workers."lastHeartbeatAt" IS NULL OR workers."lastHeartbeatAt" <= NOW() - INTERVAL '5 seconds' THEN 'INACTIVE'
            WHEN workers."isPaused" = true THEN 'PAUSED'
            ELSE 'ACTIVE'
        END = ANY($5::text[])
    )
`

type CountWorkersParams struct {
	Tenantid           uuid.UUID        `json:"tenantid"`
	ActionId           pgtype.Text      `json:"actionId"`
	LastHeartbeatAfter pgtype.Timestamp `json:"lastHeartbeatAfter"`
	Assignable         pgtype.Bool      `json:"assignable"`
	Statuses           []string         `json:"statuses"`
}

func (q *Queries) CountWorkers(ctx context.Context, db DBTX, arg CountWorkersParams) (int64, error) {
	row := db.QueryRow(ctx, countWorkers,
		arg.Tenantid,
		arg.ActionId,
		arg.LastHeartbeatAfter,
		arg.Assignable,
		arg.Statuses,
	)
	var count int64
	err := row.Scan(&count)
	return count, err
}

const createWorker = `-- name: CreateWorker :one
INSERT INTO "Worker" (
    "id",
    "createdAt",
    "updatedAt",
    "tenantId",
    "name",
    "dispatcherId",
    "type",
    "sdkVersion",
    "language",
    "languageVersion",
    "os",
    "runtimeExtra",
    "actionHash"
) VALUES (
    gen_random_uuid(),
    CURRENT_TIMESTAMP,
    CURRENT_TIMESTAMP,
    $1::uuid,
    $2::text,
    $3::uuid,
    $4::"WorkerType",
    $5::text,
    $6::"WorkerSDKS",
    $7::text,
    $8::text,
    $9::text,
    $10::bytea
) RETURNING id, "createdAt", "updatedAt", "deletedAt", "tenantId", "lastHeartbeatAt", name, "dispatcherId", "maxRuns", "isActive", "lastListenerEstablished", "isPaused", type, "webhookId", language, "languageVersion", os, "runtimeExtra", "sdkVersion", "durableTaskDispatcherId", "actionHash"
`

type CreateWorkerParams struct {
	Tenantid        uuid.UUID      `json:"tenantid"`
	Name            string         `json:"name"`
	Dispatcherid    uuid.UUID      `json:"dispatcherid"`
	Type            NullWorkerType `json:"type"`
	SdkVersion      pgtype.Text    `json:"sdkVersion"`
	Language        NullWorkerSDKS `json:"language"`
	LanguageVersion pgtype.Text    `json:"languageVersion"`
	Os              pgtype.Text    `json:"os"`
	RuntimeExtra    pgtype.Text    `json:"runtimeExtra"`
	Actionhash      []byte         `json:"actionhash"`
}

func (q *Queries) CreateWorker(ctx context.Context, db DBTX, arg CreateWorkerParams) (*Worker, error) {
	row := db.QueryRow(ctx, createWorker,
		arg.Tenantid,
		arg.Name,
		arg.Dispatcherid,
		arg.Type,
		arg.SdkVersion,
		arg.Language,
		arg.LanguageVersion,
		arg.Os,
		arg.RuntimeExtra,
		arg.Actionhash,
	)
	var i Worker
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TenantId,
		&i.LastHeartbeatAt,
		&i.Name,
		&i.DispatcherId,
		&i.MaxRuns,
		&i.IsActive,
		&i.LastListenerEstablished,
		&i.IsPaused,
		&i.Type,
		&i.WebhookId,
		&i.Language,
		&i.LanguageVersion,
		&i.Os,
		&i.RuntimeExtra,
		&i.SdkVersion,
		&i.DurableTaskDispatcherId,
		&i.ActionHash,
	)
	return &i, err
}

const createWorkerSlotConfigs = `-- name: CreateWorkerSlotConfigs :exec
INSERT INTO v1_worker_slot_config (
    tenant_id,
    worker_id,
    slot_type,
    max_units,
    created_at,
    updated_at
)
SELECT
    $1::uuid,
    $2::uuid,
    unnest($3::text[]),
    unnest($4::integer[]),
    CURRENT_TIMESTAMP,
    CURRENT_TIMESTAMP
ON CONFLICT (tenant_id, worker_id, slot_type) DO UPDATE SET
    max_units = EXCLUDED.max_units,
    updated_at = CURRENT_TIMESTAMP
`

type CreateWorkerSlotConfigsParams struct {
	Tenantid  uuid.UUID `json:"tenantid"`
	Workerid  uuid.UUID `json:"workerid"`
	Slottypes []string  `json:"slottypes"`
	Maxunits  []int32   `json:"maxunits"`
}

// NOTE: ON CONFLICT can be removed after the 0_76_d migration is run to remove insert triggers added in 0_76
func (q *Queries) CreateWorkerSlotConfigs(ctx context.Context, db DBTX, arg CreateWorkerSlotConfigsParams) error {
	_, err := db.Exec(ctx, createWorkerSlotConfigs,
		arg.Tenantid,
		arg.Workerid,
		arg.Slottypes,
		arg.Maxunits,
	)
	return err
}

const deleteWorker = `-- name: DeleteWorker :one
DELETE FROM
  "Worker"
WHERE
  "id" = $1::uuid
RETURNING id, "createdAt", "updatedAt", "deletedAt", "tenantId", "lastHeartbeatAt", name, "dispatcherId", "maxRuns", "isActive", "lastListenerEstablished", "isPaused", type, "webhookId", language, "languageVersion", os, "runtimeExtra", "sdkVersion", "durableTaskDispatcherId", "actionHash"
`

func (q *Queries) DeleteWorker(ctx context.Context, db DBTX, id uuid.UUID) (*Worker, error) {
	row := db.QueryRow(ctx, deleteWorker, id)
	var i Worker
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TenantId,
		&i.LastHeartbeatAt,
		&i.Name,
		&i.DispatcherId,
		&i.MaxRuns,
		&i.IsActive,
		&i.LastListenerEstablished,
		&i.IsPaused,
		&i.Type,
		&i.WebhookId,
		&i.Language,
		&i.LanguageVersion,
		&i.Os,
		&i.RuntimeExtra,
		&i.SdkVersion,
		&i.DurableTaskDispatcherId,
		&i.ActionHash,
	)
	return &i, err
}

const getActiveWorkerById = `-- name: GetActiveWorkerById :one
SELECT
    w.id, w."createdAt", w."updatedAt", w."deletedAt", w."tenantId", w."lastHeartbeatAt", w.name, w."dispatcherId", w."maxRuns", w."isActive", w."lastListenerEstablished", w."isPaused", w.type, w."webhookId", w.language, w."languageVersion", w.os, w."runtimeExtra", w."sdkVersion", w."durableTaskDispatcherId", w."actionHash",
    ww."url" AS "webhookUrl",
    w."maxRuns" - (
        SELECT COUNT(*)
        FROM v1_task_runtime runtime
        WHERE
            runtime.tenant_id = w."tenantId" AND
            runtime.worker_id = w."id"
    ) AS "remainingSlots"
FROM
    "Worker" w
LEFT JOIN
    "WebhookWorker" ww ON w."webhookId" = ww."id"
WHERE
    w."id" = $1::uuid
    AND w."tenantId" = $2::uuid
    AND w."dispatcherId" IS NOT NULL
    AND w."lastHeartbeatAt" > NOW() - INTERVAL '5 seconds'
    AND w."isActive" = true
    AND w."isPaused" = false
`

type GetActiveWorkerByIdParams struct {
	ID       uuid.UUID `json:"id"`
	Tenantid uuid.UUID `json:"tenantid"`
}

type GetActiveWorkerByIdRow struct {
	Worker         Worker      `json:"worker"`
	WebhookUrl     pgtype.Text `json:"webhookUrl"`
	RemainingSlots int32       `json:"remainingSlots"`
}

func (q *Queries) GetActiveWorkerById(ctx context.Context, db DBTX, arg GetActiveWorkerByIdParams) (*GetActiveWorkerByIdRow, error) {
	row := db.QueryRow(ctx, getActiveWorkerById, arg.ID, arg.Tenantid)
	var i GetActiveWorkerByIdRow
	err := row.Scan(
		&i.Worker.ID,
		&i.Worker.CreatedAt,
		&i.Worker.UpdatedAt,
		&i.Worker.DeletedAt,
		&i.Worker.TenantId,
		&i.Worker.LastHeartbeatAt,
		&i.Worker.Name,
		&i.Worker.DispatcherId,
		&i.Worker.MaxRuns,
		&i.Worker.IsActive,
		&i.Worker.LastListenerEstablished,
		&i.Worker.IsPaused,
		&i.Worker.Type,
		&i.Worker.WebhookId,
		&i.Worker.Language,
		&i.Worker.LanguageVersion,
		&i.Worker.Os,
		&i.Worker.RuntimeExtra,
		&i.Worker.SdkVersion,
		&i.Worker.DurableTaskDispatcherId,
		&i.Worker.ActionHash,
		&i.WebhookUrl,
		&i.RemainingSlots,
	)
	return &i, err
}

const getWorkerActionsByWorkerActionHash = `-- name: GetWorkerActionsByWorkerActionHash :many
SELECT DISTINCT
    w."actionHash" AS action_hash,
    a."actionId" AS action_id
FROM "Worker" w
JOIN "_ActionToWorker" aw ON w.id = aw."B"
JOIN "Action" a ON aw."A" = a.id
WHERE
    w."tenantId" = $1::UUID
    AND w."actionHash" = ANY($2::BYTEA[])
`

type GetWorkerActionsByWorkerActionHashParams struct {
	Tenantid     uuid.UUID `json:"tenantid"`
	Actionhashes [][]byte  `json:"actionhashes"`
}

type GetWorkerActionsByWorkerActionHashRow struct {
	ActionHash []byte `json:"action_hash"`
	ActionID   string `json:"action_id"`
}

func (q *Queries) GetWorkerActionsByWorkerActionHash(ctx context.Context, db DBTX, arg GetWorkerActionsByWorkerActionHashParams) ([]*GetWorkerActionsByWorkerActionHashRow, error) {
	rows, err := db.Query(ctx, getWorkerActionsByWorkerActionHash, arg.Tenantid, arg.Actionhashes)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*GetWorkerActionsByWorkerActionHashRow
	for rows.Next() {
		var i GetWorkerActionsByWorkerActionHashRow
		if err := rows.Scan(&i.ActionHash, &i.ActionID); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkerActionsByWorkerId = `-- name: GetWorkerActionsByWorkerId :many
SELECT
    w."id" AS "workerId",
    a."actionId" AS actionId
FROM "Worker" w
JOIN "_ActionToWorker" aw ON w.id = aw."B"
JOIN "Action" a ON aw."A" = a.id
WHERE
    a."tenantId" = $1::UUID
    AND w.id = ANY($2::UUID[])
`

type GetWorkerActionsByWorkerIdParams struct {
	Tenantid  uuid.UUID   `json:"tenantid"`
	Workerids []uuid.UUID `json:"workerids"`
}

type GetWorkerActionsByWorkerIdRow struct {
	WorkerId uuid.UUID `json:"workerId"`
	Actionid string    `json:"actionid"`
}

func (q *Queries) GetWorkerActionsByWorkerId(ctx context.Context, db DBTX, arg GetWorkerActionsByWorkerIdParams) ([]*GetWorkerActionsByWorkerIdRow, error) {
	rows, err := db.Query(ctx, getWorkerActionsByWorkerId, arg.Tenantid, arg.Workerids)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*GetWorkerActionsByWorkerIdRow
	for rows.Next() {
		var i GetWorkerActionsByWorkerIdRow
		if err := rows.Scan(&i.WorkerId, &i.Actionid); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const getWorkerById = `-- name: GetWorkerById :one
SELECT
    w.id, w."createdAt", w."updatedAt", w."deletedAt", w."tenantId", w."lastHeartbeatAt", w.name, w."dispatcherId", w."maxRuns", w."isActive", w."lastListenerEstablished", w."isPaused", w.type, w."webhookId", w.language, w."languageVersion", w.os, w."runtimeExtra", w."sdkVersion", w."durableTaskDispatcherId", w."actionHash"
FROM
    "Worker" w
WHERE
    w."id" = $1::uuid
`

type GetWorkerByIdRow struct {
	Worker Worker `json:"worker"`
}

func (q *Queries) GetWorkerById(ctx context.Context, db DBTX, id uuid.UUID) (*GetWorkerByIdRow, error) {
	row := db.QueryRow(ctx, getWorkerById, id)
	var i GetWorkerByIdRow
	err := row.Scan(
		&i.Worker.ID,
		&i.Worker.CreatedAt,
		&i.Worker.UpdatedAt,
		&i.Worker.DeletedAt,
		&i.Worker.TenantId,
		&i.Worker.LastHeartbeatAt,
		&i.Worker.Name,
		&i.Worker.DispatcherId,
		&i.Worker.MaxRuns,
		&i.Worker.IsActive,
		&i.Worker.LastListenerEstablished,
		&i.Worker.IsPaused,
		&i.Worker.Type,
		&i.Worker.WebhookId,
		&i.Worker.Language,
		&i.Worker.LanguageVersion,
		&i.Worker.Os,
		&i.Worker.RuntimeExtra,
		&i.Worker.SdkVersion,
		&i.Worker.DurableTaskDispatcherId,
		&i.Worker.ActionHash,
	)
	return &i, err
}

const getWorkerForEngine = `-- name: GetWorkerForEngine :one
SELECT
    w."id" AS "id",
    w."tenantId" AS "tenantId",
    w."dispatcherId" AS "dispatcherId",
    w."lastHeartbeatAt" AS "lastHeartbeatAt",
    d."lastHeartbeatAt" AS "dispatcherLastHeartbeatAt",
    w."isActive" AS "isActive",
    w."lastListenerEstablished" AS "lastListenerEstablished"
FROM
    "Worker" w
LEFT JOIN
    "Dispatcher" d ON w."dispatcherId" = d."id"
WHERE
    w."tenantId" = $1
    AND w."id" = $2
`

type GetWorkerForEngineParams struct {
	Tenantid uuid.UUID `json:"tenantid"`
	ID       uuid.UUID `json:"id"`
}

type GetWorkerForEngineRow struct {
	ID                        uuid.UUID        `json:"id"`
	TenantId                  uuid.UUID        `json:"tenantId"`
	DispatcherId              *uuid.UUID       `json:"dispatcherId"`
	LastHeartbeatAt           pgtype.Timestamp `json:"lastHeartbeatAt"`
	DispatcherLastHeartbeatAt pgtype.Timestamp `json:"dispatcherLastHeartbeatAt"`
	IsActive                  bool             `json:"isActive"`
	LastListenerEstablished   pgtype.Timestamp `json:"lastListenerEstablished"`
}

func (q *Queries) GetWorkerForEngine(ctx context.Context, db DBTX, arg GetWorkerForEngineParams) (*GetWorkerForEngineRow, error) {
	row := db.QueryRow(ctx, getWorkerForEngine, arg.Tenantid, arg.ID)
	var i GetWorkerForEngineRow
	err := row.Scan(
		&i.ID,
		&i.TenantId,
		&i.DispatcherId,
		&i.LastHeartbeatAt,
		&i.DispatcherLastHeartbeatAt,
		&i.IsActive,
		&i.LastListenerEstablished,
	)
	return &i, err
}

const getWorkerWorkflowsByWorkerId = `-- name: GetWorkerWorkflowsByWorkerId :many
SELECT wf.id, wf."createdAt", wf."updatedAt", wf."deletedAt", wf."tenantId", wf.name, wf.description, wf."isPaused"
FROM "Worker" w
JOIN "_ActionToWorker" aw ON w.id = aw."B"
JOIN "Action" a ON aw."A" = a.id
JOIN "Step" s ON s."actionId" = a."actionId" AND s."tenantId" = a."tenantId"
JOIN "Job" j ON j."id" = s."jobId" AND j."tenantId" = a."tenantId"
JOIN "WorkflowVersion" wv ON wv."id" = j."workflowVersionId"
JOIN "Workflow" wf ON wf."id" = wv."workflowId" AND wf."tenantId" = a."tenantId"
WHERE
    w."id" = $1::UUID
    AND w."tenantId" = $2::UUID
`

type GetWorkerWorkflowsByWorkerIdParams struct {
	Workerid uuid.UUID `json:"workerid"`
	Tenantid uuid.UUID `json:"tenantid"`
}

func (q *Queries) GetWorkerWorkflowsByWorkerId(ctx context.Context, db DBTX, arg GetWorkerWorkflowsByWorkerIdParams) ([]*Workflow, error) {
	rows, err := db.Query(ctx, getWorkerWorkflowsByWorkerId, arg.Workerid, arg.Tenantid)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*Workflow
	for rows.Next() {
		var i Workflow
		if err := rows.Scan(
			&i.ID,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.DeletedAt,
			&i.TenantId,
			&i.Name,
			&i.Description,
			&i.IsPaused,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const linkActionsToWorker = `-- name: LinkActionsToWorker :exec
INSERT INTO "_ActionToWorker" (
    "A",
    "B"
) SELECT
    unnest($1::uuid[]),
    $2::uuid
ON CONFLICT DO NOTHING
`

type LinkActionsToWorkerParams struct {
	Actionids []uuid.UUID `json:"actionids"`
	Workerid  uuid.UUID   `json:"workerid"`
}

func (q *Queries) LinkActionsToWorker(ctx context.Context, db DBTX, arg LinkActionsToWorkerParams) error {
	_, err := db.Exec(ctx, linkActionsToWorker, arg.Actionids, arg.Workerid)
	return err
}

const linkServicesToWorker = `-- name: LinkServicesToWorker :exec
INSERT INTO "_ServiceToWorker" (
    "A",
    "B"
)
VALUES (
    unnest($1::uuid[]),
    $2::uuid
)
ON CONFLICT DO NOTHING
`

type LinkServicesToWorkerParams struct {
	Services []uuid.UUID `json:"services"`
	Workerid uuid.UUID   `json:"workerid"`
}

func (q *Queries) LinkServicesToWorker(ctx context.Context, db DBTX, arg LinkServicesToWorkerParams) error {
	_, err := db.Exec(ctx, linkServicesToWorker, arg.Services, arg.Workerid)
	return err
}

const listActiveSDKsPerTenant = `-- name: ListActiveSDKsPerTenant :many
SELECT
    "tenantId",
    COALESCE("language"::TEXT, 'unknown')::TEXT AS "language",
    COALESCE("languageVersion", 'unknown') AS "languageVersion",
    COALESCE("sdkVersion", 'unknown') AS "sdkVersion",
    COALESCE("os", 'unknown') AS "os",
    COUNT(*) AS "count"
FROM "Worker"
WHERE
    "dispatcherId" IS NOT NULL
    AND "lastHeartbeatAt" > NOW() - INTERVAL '5 seconds'
    AND "isActive" = true
    AND "isPaused" = false
GROUP BY "tenantId", "language", "languageVersion", "sdkVersion", "os"
`

type ListActiveSDKsPerTenantRow struct {
	TenantId        uuid.UUID `json:"tenantId"`
	Language        string    `json:"language"`
	LanguageVersion string    `json:"languageVersion"`
	SdkVersion      string    `json:"sdkVersion"`
	Os              string    `json:"os"`
	Count           int64     `json:"count"`
}

func (q *Queries) ListActiveSDKsPerTenant(ctx context.Context, db DBTX) ([]*ListActiveSDKsPerTenantRow, error) {
	rows, err := db.Query(ctx, listActiveSDKsPerTenant)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListActiveSDKsPerTenantRow
	for rows.Next() {
		var i ListActiveSDKsPerTenantRow
		if err := rows.Scan(
			&i.TenantId,
			&i.Language,
			&i.LanguageVersion,
			&i.SdkVersion,
			&i.Os,
			&i.Count,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listActiveSlotsPerTenantAndSlotType = `-- name: ListActiveSlotsPerTenantAndSlotType :many
SELECT
    wc.tenant_id AS "tenantId",
    wc.slot_type AS "slotType",
    SUM(wc.max_units) AS "activeSlots"
FROM v1_worker_slot_config wc
JOIN "Worker" w ON w."id" = wc.worker_id AND w."tenantId" = wc.tenant_id
WHERE
    w."dispatcherId" IS NOT NULL
    AND w."lastHeartbeatAt" > NOW() - INTERVAL '5 seconds'
    AND w."isActive" = true
    AND w."isPaused" = false
GROUP BY wc.tenant_id, wc.slot_type
`

type ListActiveSlotsPerTenantAndSlotTypeRow struct {
	TenantId    uuid.UUID `json:"tenantId"`
	SlotType    string    `json:"slotType"`
	ActiveSlots int64     `json:"activeSlots"`
}

func (q *Queries) ListActiveSlotsPerTenantAndSlotType(ctx context.Context, db DBTX) ([]*ListActiveSlotsPerTenantAndSlotTypeRow, error) {
	rows, err := db.Query(ctx, listActiveSlotsPerTenantAndSlotType)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListActiveSlotsPerTenantAndSlotTypeRow
	for rows.Next() {
		var i ListActiveSlotsPerTenantAndSlotTypeRow
		if err := rows.Scan(&i.TenantId, &i.SlotType, &i.ActiveSlots); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listActiveWorkersPerTenant = `-- name: ListActiveWorkersPerTenant :many
SELECT "tenantId", COUNT(*)
FROM "Worker"
WHERE
    "dispatcherId" IS NOT NULL
    AND "lastHeartbeatAt" > NOW() - INTERVAL '5 seconds'
    AND "isActive" = true
    AND "isPaused" = false
GROUP BY "tenantId"
`

type ListActiveWorkersPerTenantRow struct {
	TenantId uuid.UUID `json:"tenantId"`
	Count    int64     `json:"count"`
}

func (q *Queries) ListActiveWorkersPerTenant(ctx context.Context, db DBTX) ([]*ListActiveWorkersPerTenantRow, error) {
	rows, err := db.Query(ctx, listActiveWorkersPerTenant)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListActiveWorkersPerTenantRow
	for rows.Next() {
		var i ListActiveWorkersPerTenantRow
		if err := rows.Scan(&i.TenantId, &i.Count); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listAvailableSlotsForWorkers = `-- name: ListAvailableSlotsForWorkers :many
WITH worker_capacities AS (
    SELECT
        worker_id,
        max_units
    FROM
        v1_worker_slot_config
    WHERE
        tenant_id = $1::uuid
        AND worker_id = ANY($2::uuid[])
        AND slot_type = $3::text
), worker_used_slots AS (
    SELECT
        worker_id,
        SUM(units) AS used_units
    FROM
        v1_task_runtime_slot
    WHERE
        tenant_id = $1::uuid
        AND worker_id = ANY($2::uuid[])
        AND slot_type = $3::text
    GROUP BY
        worker_id
)
SELECT
    wc.worker_id AS "id",
    wc.max_units - COALESCE(wus.used_units, 0) AS "availableSlots"
FROM
    worker_capacities wc
LEFT JOIN
    worker_used_slots wus ON wc.worker_id = wus.worker_id
`

type ListAvailableSlotsForWorkersParams struct {
	Tenantid  uuid.UUID   `json:"tenantid"`
	Workerids []uuid.UUID `json:"workerids"`
	Slottype  string      `json:"slottype"`
}

type ListAvailableSlotsForWorkersRow struct {
	ID             uuid.UUID `json:"id"`
	AvailableSlots int32     `json:"availableSlots"`
}

func (q *Queries) ListAvailableSlotsForWorkers(ctx context.Context, db DBTX, arg ListAvailableSlotsForWorkersParams) ([]*ListAvailableSlotsForWorkersRow, error) {
	rows, err := db.Query(ctx, listAvailableSlotsForWorkers, arg.Tenantid, arg.Workerids, arg.Slottype)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListAvailableSlotsForWorkersRow
	for rows.Next() {
		var i ListAvailableSlotsForWorkersRow
		if err := rows.Scan(&i.ID, &i.AvailableSlots); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listAvailableSlotsForWorkersAndTypes = `-- name: ListAvailableSlotsForWorkersAndTypes :many
WITH worker_capacities AS (
    SELECT
        worker_id,
        slot_type,
        max_units
    FROM
        v1_worker_slot_config
    WHERE
        tenant_id = $1::uuid
        AND worker_id = ANY($2::uuid[])
        AND slot_type = ANY($3::text[])
), worker_used_slots AS (
    SELECT
        worker_id,
        slot_type,
        SUM(units) AS used_units
    FROM
        v1_task_runtime_slot
    WHERE
        tenant_id = $1::uuid
        AND worker_id = ANY($2::uuid[])
        AND slot_type = ANY($3::text[])
    GROUP BY
        worker_id,
        slot_type
)
SELECT
    wc.worker_id AS "id",
    wc.slot_type AS "slotType",
    wc.max_units - COALESCE(wus.used_units, 0) AS "availableSlots"
FROM
    worker_capacities wc
LEFT JOIN
    worker_used_slots wus ON wc.worker_id = wus.worker_id AND wc.slot_type = wus.slot_type
`

type ListAvailableSlotsForWorkersAndTypesParams struct {
	Tenantid  uuid.UUID   `json:"tenantid"`
	Workerids []uuid.UUID `json:"workerids"`
	Slottypes []string    `json:"slottypes"`
}

type ListAvailableSlotsForWorkersAndTypesRow struct {
	ID             uuid.UUID `json:"id"`
	SlotType       string    `json:"slotType"`
	AvailableSlots int32     `json:"availableSlots"`
}

func (q *Queries) ListAvailableSlotsForWorkersAndTypes(ctx context.Context, db DBTX, arg ListAvailableSlotsForWorkersAndTypesParams) ([]*ListAvailableSlotsForWorkersAndTypesRow, error) {
	rows, err := db.Query(ctx, listAvailableSlotsForWorkersAndTypes, arg.Tenantid, arg.Workerids, arg.Slottypes)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListAvailableSlotsForWorkersAndTypesRow
	for rows.Next() {
		var i ListAvailableSlotsForWorkersAndTypesRow
		if err := rows.Scan(&i.ID, &i.SlotType, &i.AvailableSlots); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listDispatcherIdsForWorkers = `-- name: ListDispatcherIdsForWorkers :many
SELECT
    "id" as "workerId",
    "dispatcherId"
FROM
    "Worker"
WHERE
    "tenantId" = $1::uuid
    AND "id" = ANY($2::uuid[])
`

type ListDispatcherIdsForWorkersParams struct {
	Tenantid  uuid.UUID   `json:"tenantid"`
	Workerids []uuid.UUID `json:"workerids"`
}

type ListDispatcherIdsForWorkersRow struct {
	WorkerId     uuid.UUID  `json:"workerId"`
	DispatcherId *uuid.UUID `json:"dispatcherId"`
}

func (q *Queries) ListDispatcherIdsForWorkers(ctx context.Context, db DBTX, arg ListDispatcherIdsForWorkersParams) ([]*ListDispatcherIdsForWorkersRow, error) {
	rows, err := db.Query(ctx, listDispatcherIdsForWorkers, arg.Tenantid, arg.Workerids)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListDispatcherIdsForWorkersRow
	for rows.Next() {
		var i ListDispatcherIdsForWorkersRow
		if err := rows.Scan(&i.WorkerId, &i.DispatcherId); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listDurableTaskDispatcherIdsForTasks = `-- name: ListDurableTaskDispatcherIdsForTasks :many
WITH tasks AS (
    SELECT
        UNNEST($2::BIGINT[]) AS task_id,
        UNNEST($3::TIMESTAMPTZ[]) AS task_inserted_at
)

SELECT
    rt.task_id, rt.task_inserted_at, rt.retry_count, rt.worker_id, rt.tenant_id, rt.timeout_at, rt.evicted_at,
    w."durableTaskDispatcherId"
FROM v1_task_runtime rt
LEFT JOIN "Worker" w ON rt.worker_id = w.id
WHERE
    rt.tenant_id = $1::uuid
    AND (rt.task_id, rt.task_inserted_at) IN (
        SELECT task_id, task_inserted_at
        FROM tasks
    )
`

type ListDurableTaskDispatcherIdsForTasksParams struct {
	Tenantid        uuid.UUID            `json:"tenantid"`
	Taskids         []int64              `json:"taskids"`
	Taskinsertedats []pgtype.Timestamptz `json:"taskinsertedats"`
}

type ListDurableTaskDispatcherIdsForTasksRow struct {
	TaskID                  int64              `json:"task_id"`
	TaskInsertedAt          pgtype.Timestamptz `json:"task_inserted_at"`
	RetryCount              int32              `json:"retry_count"`
	WorkerID                *uuid.UUID         `json:"worker_id"`
	TenantID                uuid.UUID          `json:"tenant_id"`
	TimeoutAt               pgtype.Timestamp   `json:"timeout_at"`
	EvictedAt               pgtype.Timestamptz `json:"evicted_at"`
	DurableTaskDispatcherId *uuid.UUID         `json:"durableTaskDispatcherId"`
}

func (q *Queries) ListDurableTaskDispatcherIdsForTasks(ctx context.Context, db DBTX, arg ListDurableTaskDispatcherIdsForTasksParams) ([]*ListDurableTaskDispatcherIdsForTasksRow, error) {
	rows, err := db.Query(ctx, listDurableTaskDispatcherIdsForTasks, arg.Tenantid, arg.Taskids, arg.Taskinsertedats)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListDurableTaskDispatcherIdsForTasksRow
	for rows.Next() {
		var i ListDurableTaskDispatcherIdsForTasksRow
		if err := rows.Scan(
			&i.TaskID,
			&i.TaskInsertedAt,
			&i.RetryCount,
			&i.WorkerID,
			&i.TenantID,
			&i.TimeoutAt,
			&i.EvictedAt,
			&i.DurableTaskDispatcherId,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listManyWorkerLabels = `-- name: ListManyWorkerLabels :many
SELECT
    "id",
    "key",
    "intValue",
    "strValue",
    "createdAt",
    "updatedAt",
    "workerId"
FROM "WorkerLabel" wl
WHERE wl."workerId" = ANY($1::uuid[])
`

type ListManyWorkerLabelsRow struct {
	ID        int64            `json:"id"`
	Key       string           `json:"key"`
	IntValue  pgtype.Int4      `json:"intValue"`
	StrValue  pgtype.Text      `json:"strValue"`
	CreatedAt pgtype.Timestamp `json:"createdAt"`
	UpdatedAt pgtype.Timestamp `json:"updatedAt"`
	WorkerId  uuid.UUID        `json:"workerId"`
}

func (q *Queries) ListManyWorkerLabels(ctx context.Context, db DBTX, workerids []uuid.UUID) ([]*ListManyWorkerLabelsRow, error) {
	rows, err := db.Query(ctx, listManyWorkerLabels, workerids)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListManyWorkerLabelsRow
	for rows.Next() {
		var i ListManyWorkerLabelsRow
		if err := rows.Scan(
			&i.ID,
			&i.Key,
			&i.IntValue,
			&i.StrValue,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.WorkerId,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listSemaphoreSlotsWithStateForWorker = `-- name: ListSemaphoreSlotsWithStateForWorker :many
SELECT
    task_id, task_inserted_at, runtime.retry_count, worker_id, runtime.tenant_id, timeout_at, evicted_at, id, inserted_at, v1_task.tenant_id, queue, action_id, step_id, step_readable_id, workflow_id, workflow_version_id, workflow_run_id, schedule_timeout, step_timeout, priority, sticky, desired_worker_id, external_id, display_name, input, v1_task.retry_count, internal_retry_count, app_retry_count, step_index, additional_metadata, dag_id, dag_inserted_at, parent_task_external_id, parent_task_id, parent_task_inserted_at, child_index, child_key, initial_state, initial_state_reason, concurrency_parent_strategy_ids, concurrency_strategy_ids, concurrency_keys, retry_backoff_factor, retry_max_backoff, is_durable, desired_worker_label, triggering_event_external_id, triggering_event_key
FROM
    v1_task_runtime runtime
JOIN
    v1_task ON runtime.task_id = v1_task.id AND runtime.task_inserted_at = v1_task.inserted_at
WHERE
    runtime.tenant_id = $1::uuid
    AND runtime.worker_id = $2::uuid
LIMIT
    COALESCE($3::int, 100)
`

type ListSemaphoreSlotsWithStateForWorkerParams struct {
	Tenantid uuid.UUID   `json:"tenantid"`
	Workerid uuid.UUID   `json:"workerid"`
	Limit    pgtype.Int4 `json:"limit"`
}

type ListSemaphoreSlotsWithStateForWorkerRow struct {
	TaskID                       int64              `json:"task_id"`
	TaskInsertedAt               pgtype.Timestamptz `json:"task_inserted_at"`
	RetryCount                   int32              `json:"retry_count"`
	WorkerID                     *uuid.UUID         `json:"worker_id"`
	TenantID                     uuid.UUID          `json:"tenant_id"`
	TimeoutAt                    pgtype.Timestamp   `json:"timeout_at"`
	EvictedAt                    pgtype.Timestamptz `json:"evicted_at"`
	ID                           int64              `json:"id"`
	InsertedAt                   pgtype.Timestamptz `json:"inserted_at"`
	TenantID_2                   uuid.UUID          `json:"tenant_id_2"`
	Queue                        string             `json:"queue"`
	ActionID                     string             `json:"action_id"`
	StepID                       uuid.UUID          `json:"step_id"`
	StepReadableID               string             `json:"step_readable_id"`
	WorkflowID                   uuid.UUID          `json:"workflow_id"`
	WorkflowVersionID            uuid.UUID          `json:"workflow_version_id"`
	WorkflowRunID                uuid.UUID          `json:"workflow_run_id"`
	ScheduleTimeout              string             `json:"schedule_timeout"`
	StepTimeout                  pgtype.Text        `json:"step_timeout"`
	Priority                     pgtype.Int4        `json:"priority"`
	Sticky                       V1StickyStrategy   `json:"sticky"`
	DesiredWorkerID              *uuid.UUID         `json:"desired_worker_id"`
	ExternalID                   uuid.UUID          `json:"external_id"`
	DisplayName                  string             `json:"display_name"`
	Input                        []byte             `json:"input"`
	RetryCount_2                 int32              `json:"retry_count_2"`
	InternalRetryCount           int32              `json:"internal_retry_count"`
	AppRetryCount                int32              `json:"app_retry_count"`
	StepIndex                    int64              `json:"step_index"`
	AdditionalMetadata           []byte             `json:"additional_metadata"`
	DagID                        pgtype.Int8        `json:"dag_id"`
	DagInsertedAt                pgtype.Timestamptz `json:"dag_inserted_at"`
	ParentTaskExternalID         *uuid.UUID         `json:"parent_task_external_id"`
	ParentTaskID                 pgtype.Int8        `json:"parent_task_id"`
	ParentTaskInsertedAt         pgtype.Timestamptz `json:"parent_task_inserted_at"`
	ChildIndex                   pgtype.Int8        `json:"child_index"`
	ChildKey                     pgtype.Text        `json:"child_key"`
	InitialState                 V1TaskInitialState `json:"initial_state"`
	InitialStateReason           pgtype.Text        `json:"initial_state_reason"`
	ConcurrencyParentStrategyIds []pgtype.Int8      `json:"concurrency_parent_strategy_ids"`
	ConcurrencyStrategyIds       []int64            `json:"concurrency_strategy_ids"`
	ConcurrencyKeys              []string           `json:"concurrency_keys"`
	RetryBackoffFactor           pgtype.Float8      `json:"retry_backoff_factor"`
	RetryMaxBackoff              pgtype.Int4        `json:"retry_max_backoff"`
	IsDurable                    pgtype.Bool        `json:"is_durable"`
	DesiredWorkerLabel           []byte             `json:"desired_worker_label"`
	TriggeringEventExternalID    *uuid.UUID         `json:"triggering_event_external_id"`
	TriggeringEventKey           pgtype.Text        `json:"triggering_event_key"`
}

func (q *Queries) ListSemaphoreSlotsWithStateForWorker(ctx context.Context, db DBTX, arg ListSemaphoreSlotsWithStateForWorkerParams) ([]*ListSemaphoreSlotsWithStateForWorkerRow, error) {
	rows, err := db.Query(ctx, listSemaphoreSlotsWithStateForWorker, arg.Tenantid, arg.Workerid, arg.Limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListSemaphoreSlotsWithStateForWorkerRow
	for rows.Next() {
		var i ListSemaphoreSlotsWithStateForWorkerRow
		if err := rows.Scan(
			&i.TaskID,
			&i.TaskInsertedAt,
			&i.RetryCount,
			&i.WorkerID,
			&i.TenantID,
			&i.TimeoutAt,
			&i.EvictedAt,
			&i.ID,
			&i.InsertedAt,
			&i.TenantID_2,
			&i.Queue,
			&i.ActionID,
			&i.StepID,
			&i.StepReadableID,
			&i.WorkflowID,
			&i.WorkflowVersionID,
			&i.WorkflowRunID,
			&i.ScheduleTimeout,
			&i.StepTimeout,
			&i.Priority,
			&i.Sticky,
			&i.DesiredWorkerID,
			&i.ExternalID,
			&i.DisplayName,
			&i.Input,
			&i.RetryCount_2,
			&i.InternalRetryCount,
			&i.AppRetryCount,
			&i.StepIndex,
			&i.AdditionalMetadata,
			&i.DagID,
			&i.DagInsertedAt,
			&i.ParentTaskExternalID,
			&i.ParentTaskID,
			&i.ParentTaskInsertedAt,
			&i.ChildIndex,
			&i.ChildKey,
			&i.InitialState,
			&i.InitialStateReason,
			&i.ConcurrencyParentStrategyIds,
			&i.ConcurrencyStrategyIds,
			&i.ConcurrencyKeys,
			&i.RetryBackoffFactor,
			&i.RetryMaxBackoff,
			&i.IsDurable,
			&i.DesiredWorkerLabel,
			&i.TriggeringEventExternalID,
			&i.TriggeringEventKey,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listTotalActiveSlotsPerTenant = `-- name: ListTotalActiveSlotsPerTenant :many
SELECT
    wc.tenant_id AS "tenantId",
    SUM(wc.max_units) AS "totalActiveSlots"
FROM v1_worker_slot_config wc
JOIN "Worker" w ON w."id" = wc.worker_id AND w."tenantId" = wc.tenant_id
WHERE
    w."dispatcherId" IS NOT NULL
    AND w."lastHeartbeatAt" > NOW() - INTERVAL '5 seconds'
    AND w."isActive" = true
    AND w."isPaused" = false
GROUP BY wc.tenant_id
`

type ListTotalActiveSlotsPerTenantRow struct {
	TenantId         uuid.UUID `json:"tenantId"`
	TotalActiveSlots int64     `json:"totalActiveSlots"`
}

func (q *Queries) ListTotalActiveSlotsPerTenant(ctx context.Context, db DBTX) ([]*ListTotalActiveSlotsPerTenantRow, error) {
	rows, err := db.Query(ctx, listTotalActiveSlotsPerTenant)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListTotalActiveSlotsPerTenantRow
	for rows.Next() {
		var i ListTotalActiveSlotsPerTenantRow
		if err := rows.Scan(&i.TenantId, &i.TotalActiveSlots); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listWorkerLabels = `-- name: ListWorkerLabels :many
SELECT
    "workerId",
    "id",
    "key",
    "intValue",
    "strValue",
    "createdAt",
    "updatedAt"
FROM "WorkerLabel" wl
WHERE wl."workerId" = ANY($1::uuid[])
`

type ListWorkerLabelsRow struct {
	WorkerId  uuid.UUID        `json:"workerId"`
	ID        int64            `json:"id"`
	Key       string           `json:"key"`
	IntValue  pgtype.Int4      `json:"intValue"`
	StrValue  pgtype.Text      `json:"strValue"`
	CreatedAt pgtype.Timestamp `json:"createdAt"`
	UpdatedAt pgtype.Timestamp `json:"updatedAt"`
}

func (q *Queries) ListWorkerLabels(ctx context.Context, db DBTX, workerids []uuid.UUID) ([]*ListWorkerLabelsRow, error) {
	rows, err := db.Query(ctx, listWorkerLabels, workerids)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListWorkerLabelsRow
	for rows.Next() {
		var i ListWorkerLabelsRow
		if err := rows.Scan(
			&i.WorkerId,
			&i.ID,
			&i.Key,
			&i.IntValue,
			&i.StrValue,
			&i.CreatedAt,
			&i.UpdatedAt,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listWorkerSlotConfigs = `-- name: ListWorkerSlotConfigs :many
SELECT
    worker_id,
    slot_type,
    max_units
FROM
    v1_worker_slot_config
WHERE
    tenant_id = $1::uuid
    AND worker_id = ANY($2::uuid[])
`

type ListWorkerSlotConfigsParams struct {
	Tenantid  uuid.UUID   `json:"tenantid"`
	Workerids []uuid.UUID `json:"workerids"`
}

type ListWorkerSlotConfigsRow struct {
	WorkerID uuid.UUID `json:"worker_id"`
	SlotType string    `json:"slot_type"`
	MaxUnits int32     `json:"max_units"`
}

func (q *Queries) ListWorkerSlotConfigs(ctx context.Context, db DBTX, arg ListWorkerSlotConfigsParams) ([]*ListWorkerSlotConfigsRow, error) {
	rows, err := db.Query(ctx, listWorkerSlotConfigs, arg.Tenantid, arg.Workerids)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListWorkerSlotConfigsRow
	for rows.Next() {
		var i ListWorkerSlotConfigsRow
		if err := rows.Scan(&i.WorkerID, &i.SlotType, &i.MaxUnits); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listWorkers = `-- name: ListWorkers :many
SELECT
    workers.id, workers."createdAt", workers."updatedAt", workers."deletedAt", workers."tenantId", workers."lastHeartbeatAt", workers.name, workers."dispatcherId", workers."maxRuns", workers."isActive", workers."lastListenerEstablished", workers."isPaused", workers.type, workers."webhookId", workers.language, workers."languageVersion", workers.os, workers."runtimeExtra", workers."sdkVersion", workers."durableTaskDispatcherId", workers."actionHash"
FROM
    "Worker" workers
WHERE
    workers."tenantId" = $1
    AND (
        $2::text IS NULL OR
        workers."id" IN (
            SELECT "_ActionToWorker"."B"
            FROM "_ActionToWorker"
            INNER JOIN "Action" ON "Action"."id" = "_ActionToWorker"."A"
            WHERE "Action"."tenantId" = $1 AND "Action"."actionId" = $2::text
        )
    )
    AND (
        $3::timestamp IS NULL OR
        workers."lastHeartbeatAt" > $3::timestamp
    )
    AND (
        $4::boolean IS NULL OR
        ($4::boolean AND (
            SELECT COALESCE(SUM(cap.max_units), 0)
            FROM v1_worker_slot_config cap
            WHERE cap.tenant_id = workers."tenantId" AND cap.worker_id = workers."id"
        ) > (
            SELECT COALESCE(SUM(runtime.units), 0)
            FROM v1_task_runtime_slot runtime
            WHERE runtime.tenant_id = workers."tenantId" AND runtime.worker_id = workers."id"
        ))
    )
    AND (
        $5::text[] IS NULL OR
        CASE
            WHEN workers."lastHeartbeatAt" IS NULL OR workers."lastHeartbeatAt" <= NOW() - INTERVAL '5 seconds' THEN 'INACTIVE'
            WHEN workers."isPaused" = true THEN 'PAUSED'
            ELSE 'ACTIVE'
        END = ANY($5::text[])
    )
ORDER BY
    workers."createdAt" DESC
OFFSET
    COALESCE($6, 0)
LIMIT
    COALESCE($7, 10000)
`

type ListWorkersParams struct {
	Tenantid           uuid.UUID        `json:"tenantid"`
	ActionId           pgtype.Text      `json:"actionId"`
	LastHeartbeatAfter pgtype.Timestamp `json:"lastHeartbeatAfter"`
	Assignable         pgtype.Bool      `json:"assignable"`
	Statuses           []string         `json:"statuses"`
	Offset             interface{}      `json:"offset"`
	Limit              interface{}      `json:"limit"`
}

type ListWorkersRow struct {
	Worker Worker `json:"worker"`
}

func (q *Queries) ListWorkers(ctx context.Context, db DBTX, arg ListWorkersParams) ([]*ListWorkersRow, error) {
	rows, err := db.Query(ctx, listWorkers,
		arg.Tenantid,
		arg.ActionId,
		arg.LastHeartbeatAfter,
		arg.Assignable,
		arg.Statuses,
		arg.Offset,
		arg.Limit,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*ListWorkersRow
	for rows.Next() {
		var i ListWorkersRow
		if err := rows.Scan(
			&i.Worker.ID,
			&i.Worker.CreatedAt,
			&i.Worker.UpdatedAt,
			&i.Worker.DeletedAt,
			&i.Worker.TenantId,
			&i.Worker.LastHeartbeatAt,
			&i.Worker.Name,
			&i.Worker.DispatcherId,
			&i.Worker.MaxRuns,
			&i.Worker.IsActive,
			&i.Worker.LastListenerEstablished,
			&i.Worker.IsPaused,
			&i.Worker.Type,
			&i.Worker.WebhookId,
			&i.Worker.Language,
			&i.Worker.LanguageVersion,
			&i.Worker.Os,
			&i.Worker.RuntimeExtra,
			&i.Worker.SdkVersion,
			&i.Worker.DurableTaskDispatcherId,
			&i.Worker.ActionHash,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const updateWorker = `-- name: UpdateWorker :one
UPDATE
    "Worker"
SET
    "updatedAt" = CURRENT_TIMESTAMP,
    "dispatcherId" = coalesce($1::uuid, "dispatcherId"),
    "lastHeartbeatAt" = coalesce($2::timestamp, "lastHeartbeatAt"),
    "isActive" = coalesce($3::boolean, "isActive"),
    "isPaused" = coalesce($4::boolean, "isPaused")
WHERE
    "id" = $5::uuid
RETURNING id, "createdAt", "updatedAt", "deletedAt", "tenantId", "lastHeartbeatAt", name, "dispatcherId", "maxRuns", "isActive", "lastListenerEstablished", "isPaused", type, "webhookId", language, "languageVersion", os, "runtimeExtra", "sdkVersion", "durableTaskDispatcherId", "actionHash"
`

type UpdateWorkerParams struct {
	DispatcherId    *uuid.UUID       `json:"dispatcherId"`
	LastHeartbeatAt pgtype.Timestamp `json:"lastHeartbeatAt"`
	IsActive        pgtype.Bool      `json:"isActive"`
	IsPaused        pgtype.Bool      `json:"isPaused"`
	ID              uuid.UUID        `json:"id"`
}

func (q *Queries) UpdateWorker(ctx context.Context, db DBTX, arg UpdateWorkerParams) (*Worker, error) {
	row := db.QueryRow(ctx, updateWorker,
		arg.DispatcherId,
		arg.LastHeartbeatAt,
		arg.IsActive,
		arg.IsPaused,
		arg.ID,
	)
	var i Worker
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TenantId,
		&i.LastHeartbeatAt,
		&i.Name,
		&i.DispatcherId,
		&i.MaxRuns,
		&i.IsActive,
		&i.LastListenerEstablished,
		&i.IsPaused,
		&i.Type,
		&i.WebhookId,
		&i.Language,
		&i.LanguageVersion,
		&i.Os,
		&i.RuntimeExtra,
		&i.SdkVersion,
		&i.DurableTaskDispatcherId,
		&i.ActionHash,
	)
	return &i, err
}

const updateWorkerActiveStatus = `-- name: UpdateWorkerActiveStatus :one
UPDATE "Worker"
SET
    "isActive" = $1::boolean,
    "lastListenerEstablished" = $2::timestamp
WHERE
    "id" = $3::uuid
    AND (
        "lastListenerEstablished" IS NULL
        OR "lastListenerEstablished" <= $2::timestamp
        )
RETURNING id, "createdAt", "updatedAt", "deletedAt", "tenantId", "lastHeartbeatAt", name, "dispatcherId", "maxRuns", "isActive", "lastListenerEstablished", "isPaused", type, "webhookId", language, "languageVersion", os, "runtimeExtra", "sdkVersion", "durableTaskDispatcherId", "actionHash"
`

type UpdateWorkerActiveStatusParams struct {
	Isactive                bool             `json:"isactive"`
	LastListenerEstablished pgtype.Timestamp `json:"lastListenerEstablished"`
	ID                      uuid.UUID        `json:"id"`
}

func (q *Queries) UpdateWorkerActiveStatus(ctx context.Context, db DBTX, arg UpdateWorkerActiveStatusParams) (*Worker, error) {
	row := db.QueryRow(ctx, updateWorkerActiveStatus, arg.Isactive, arg.LastListenerEstablished, arg.ID)
	var i Worker
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TenantId,
		&i.LastHeartbeatAt,
		&i.Name,
		&i.DispatcherId,
		&i.MaxRuns,
		&i.IsActive,
		&i.LastListenerEstablished,
		&i.IsPaused,
		&i.Type,
		&i.WebhookId,
		&i.Language,
		&i.LanguageVersion,
		&i.Os,
		&i.RuntimeExtra,
		&i.SdkVersion,
		&i.DurableTaskDispatcherId,
		&i.ActionHash,
	)
	return &i, err
}

const updateWorkerDurableTaskDispatcherId = `-- name: UpdateWorkerDurableTaskDispatcherId :one
UPDATE "Worker"
SET
    "durableTaskDispatcherId" = $1::UUID,
    "updatedAt" = CURRENT_TIMESTAMP
WHERE
    "id" = $2::uuid
    AND "tenantId" = $3::uuid
RETURNING id, "createdAt", "updatedAt", "deletedAt", "tenantId", "lastHeartbeatAt", name, "dispatcherId", "maxRuns", "isActive", "lastListenerEstablished", "isPaused", type, "webhookId", language, "languageVersion", os, "runtimeExtra", "sdkVersion", "durableTaskDispatcherId", "actionHash"
`

type UpdateWorkerDurableTaskDispatcherIdParams struct {
	Dispatcherid uuid.UUID `json:"dispatcherid"`
	Workerid     uuid.UUID `json:"workerid"`
	Tenantid     uuid.UUID `json:"tenantid"`
}

func (q *Queries) UpdateWorkerDurableTaskDispatcherId(ctx context.Context, db DBTX, arg UpdateWorkerDurableTaskDispatcherIdParams) (*Worker, error) {
	row := db.QueryRow(ctx, updateWorkerDurableTaskDispatcherId, arg.Dispatcherid, arg.Workerid, arg.Tenantid)
	var i Worker
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TenantId,
		&i.LastHeartbeatAt,
		&i.Name,
		&i.DispatcherId,
		&i.MaxRuns,
		&i.IsActive,
		&i.LastListenerEstablished,
		&i.IsPaused,
		&i.Type,
		&i.WebhookId,
		&i.Language,
		&i.LanguageVersion,
		&i.Os,
		&i.RuntimeExtra,
		&i.SdkVersion,
		&i.DurableTaskDispatcherId,
		&i.ActionHash,
	)
	return &i, err
}

const updateWorkerHeartbeat = `-- name: UpdateWorkerHeartbeat :one
UPDATE
    "Worker"
SET
    "updatedAt" = CURRENT_TIMESTAMP,
    "lastHeartbeatAt" = $1::timestamp
WHERE
    "id" = $2::uuid
RETURNING id, "createdAt", "updatedAt", "deletedAt", "tenantId", "lastHeartbeatAt", name, "dispatcherId", "maxRuns", "isActive", "lastListenerEstablished", "isPaused", type, "webhookId", language, "languageVersion", os, "runtimeExtra", "sdkVersion", "durableTaskDispatcherId", "actionHash"
`

type UpdateWorkerHeartbeatParams struct {
	LastHeartbeatAt pgtype.Timestamp `json:"lastHeartbeatAt"`
	ID              uuid.UUID        `json:"id"`
}

func (q *Queries) UpdateWorkerHeartbeat(ctx context.Context, db DBTX, arg UpdateWorkerHeartbeatParams) (*Worker, error) {
	row := db.QueryRow(ctx, updateWorkerHeartbeat, arg.LastHeartbeatAt, arg.ID)
	var i Worker
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.TenantId,
		&i.LastHeartbeatAt,
		&i.Name,
		&i.DispatcherId,
		&i.MaxRuns,
		&i.IsActive,
		&i.LastListenerEstablished,
		&i.IsPaused,
		&i.Type,
		&i.WebhookId,
		&i.Language,
		&i.LanguageVersion,
		&i.Os,
		&i.RuntimeExtra,
		&i.SdkVersion,
		&i.DurableTaskDispatcherId,
		&i.ActionHash,
	)
	return &i, err
}

const upsertService = `-- name: UpsertService :one
INSERT INTO "Service" (
    "id",
    "createdAt",
    "updatedAt",
    "name",
    "tenantId"
)
VALUES (
    gen_random_uuid(),
    CURRENT_TIMESTAMP,
    CURRENT_TIMESTAMP,
    $1::text,
    $2::uuid
)
ON CONFLICT ("tenantId", "name") DO UPDATE
SET
    "updatedAt" = CURRENT_TIMESTAMP
WHERE
    "Service"."tenantId" = $2 AND "Service"."name" = $1::text
RETURNING id, "createdAt", "updatedAt", "deletedAt", name, description, "tenantId"
`

type UpsertServiceParams struct {
	Name     string    `json:"name"`
	Tenantid uuid.UUID `json:"tenantid"`
}

func (q *Queries) UpsertService(ctx context.Context, db DBTX, arg UpsertServiceParams) (*Service, error) {
	row := db.QueryRow(ctx, upsertService, arg.Name, arg.Tenantid)
	var i Service
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.DeletedAt,
		&i.Name,
		&i.Description,
		&i.TenantId,
	)
	return &i, err
}

const upsertWorkerLabel = `-- name: UpsertWorkerLabel :one
INSERT INTO "WorkerLabel" (
    "createdAt",
    "updatedAt",
    "workerId",
    "key",
    "intValue",
    "strValue"
) VALUES (
    CURRENT_TIMESTAMP,
    CURRENT_TIMESTAMP,
    $1::uuid,
    $2::text,
    $3::int,
    $4::text
) ON CONFLICT ("workerId", "key") DO UPDATE
SET
    "updatedAt" = CURRENT_TIMESTAMP,
    "intValue" = $3::int,
    "strValue" = $4::text
RETURNING id, "createdAt", "updatedAt", "workerId", key, "strValue", "intValue"
`

type UpsertWorkerLabelParams struct {
	Workerid uuid.UUID   `json:"workerid"`
	Key      string      `json:"key"`
	IntValue pgtype.Int4 `json:"intValue"`
	StrValue pgtype.Text `json:"strValue"`
}

func (q *Queries) UpsertWorkerLabel(ctx context.Context, db DBTX, arg UpsertWorkerLabelParams) (*WorkerLabel, error) {
	row := db.QueryRow(ctx, upsertWorkerLabel,
		arg.Workerid,
		arg.Key,
		arg.IntValue,
		arg.StrValue,
	)
	var i WorkerLabel
	err := row.Scan(
		&i.ID,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.WorkerId,
		&i.Key,
		&i.StrValue,
		&i.IntValue,
	)
	return &i, err
}
