// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.27.0
// source: tasks.sql

package querier

import (
	"context"
	"time"

	"github.com/cloudcarver/anclax/pkg/zgen/apigen"
)

const createTask = `-- name: CreateTask :one
INSERT INTO anclax.tasks (attributes, spec, status, started_at, unique_tag)
VALUES ($1, $2, $3, $4, $5) ON CONFLICT (unique_tag) DO NOTHING RETURNING id, attributes, spec, status, unique_tag, started_at, created_at, updated_at, attempts
`

type CreateTaskParams struct {
	Attributes apigen.TaskAttributes
	Spec       apigen.TaskSpec
	Status     string
	StartedAt  *time.Time
	UniqueTag  *string
}

func (q *Queries) CreateTask(ctx context.Context, arg CreateTaskParams) (*AnclaxTask, error) {
	row := q.db.QueryRow(ctx, createTask,
		arg.Attributes,
		arg.Spec,
		arg.Status,
		arg.StartedAt,
		arg.UniqueTag,
	)
	var i AnclaxTask
	err := row.Scan(
		&i.ID,
		&i.Attributes,
		&i.Spec,
		&i.Status,
		&i.UniqueTag,
		&i.StartedAt,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Attempts,
	)
	return &i, err
}

const getTaskByID = `-- name: GetTaskByID :one
SELECT id, attributes, spec, status, unique_tag, started_at, created_at, updated_at, attempts FROM anclax.tasks
WHERE id = $1
`

func (q *Queries) GetTaskByID(ctx context.Context, id int32) (*AnclaxTask, error) {
	row := q.db.QueryRow(ctx, getTaskByID, id)
	var i AnclaxTask
	err := row.Scan(
		&i.ID,
		&i.Attributes,
		&i.Spec,
		&i.Status,
		&i.UniqueTag,
		&i.StartedAt,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Attempts,
	)
	return &i, err
}

const getTaskByUniqueTag = `-- name: GetTaskByUniqueTag :one
SELECT id, attributes, spec, status, unique_tag, started_at, created_at, updated_at, attempts FROM anclax.tasks
WHERE unique_tag = $1
`

func (q *Queries) GetTaskByUniqueTag(ctx context.Context, uniqueTag *string) (*AnclaxTask, error) {
	row := q.db.QueryRow(ctx, getTaskByUniqueTag, uniqueTag)
	var i AnclaxTask
	err := row.Scan(
		&i.ID,
		&i.Attributes,
		&i.Spec,
		&i.Status,
		&i.UniqueTag,
		&i.StartedAt,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Attempts,
	)
	return &i, err
}

const incrementAttempts = `-- name: IncrementAttempts :exec
UPDATE anclax.tasks
SET attempts = attempts + 1, updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

func (q *Queries) IncrementAttempts(ctx context.Context, id int32) error {
	_, err := q.db.Exec(ctx, incrementAttempts, id)
	return err
}

const insertEvent = `-- name: InsertEvent :one
INSERT INTO anclax.events (spec)
VALUES ($1)
RETURNING id, spec, created_at
`

func (q *Queries) InsertEvent(ctx context.Context, spec apigen.EventSpec) (*AnclaxEvent, error) {
	row := q.db.QueryRow(ctx, insertEvent, spec)
	var i AnclaxEvent
	err := row.Scan(&i.ID, &i.Spec, &i.CreatedAt)
	return &i, err
}

const listAllPendingTasks = `-- name: ListAllPendingTasks :many
SELECT id, attributes, spec, status, unique_tag, started_at, created_at, updated_at, attempts FROM anclax.tasks
WHERE 
    status = 'pending'
    AND (
        started_at IS NULL OR started_at < NOW()
    )
FOR UPDATE SKIP LOCKED
`

func (q *Queries) ListAllPendingTasks(ctx context.Context) ([]*AnclaxTask, error) {
	rows, err := q.db.Query(ctx, listAllPendingTasks)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []*AnclaxTask
	for rows.Next() {
		var i AnclaxTask
		if err := rows.Scan(
			&i.ID,
			&i.Attributes,
			&i.Spec,
			&i.Status,
			&i.UniqueTag,
			&i.StartedAt,
			&i.CreatedAt,
			&i.UpdatedAt,
			&i.Attempts,
		); err != nil {
			return nil, err
		}
		items = append(items, &i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const pullTask = `-- name: PullTask :one
SELECT id, attributes, spec, status, unique_tag, started_at, created_at, updated_at, attempts FROM anclax.tasks
WHERE 
    status = 'pending'
    AND (
        started_at IS NULL OR started_at < NOW()
    )
ORDER BY RANDOM()
FOR UPDATE SKIP LOCKED
LIMIT 1
`

func (q *Queries) PullTask(ctx context.Context) (*AnclaxTask, error) {
	row := q.db.QueryRow(ctx, pullTask)
	var i AnclaxTask
	err := row.Scan(
		&i.ID,
		&i.Attributes,
		&i.Spec,
		&i.Status,
		&i.UniqueTag,
		&i.StartedAt,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Attempts,
	)
	return &i, err
}

const pullTaskByID = `-- name: PullTaskByID :one
SELECT id, attributes, spec, status, unique_tag, started_at, created_at, updated_at, attempts FROM anclax.tasks
WHERE 
    status = 'pending'
    AND id = $1
    AND (
        started_at IS NULL OR started_at < NOW()
    )
ORDER BY created_at ASC
FOR UPDATE SKIP LOCKED
`

func (q *Queries) PullTaskByID(ctx context.Context, id int32) (*AnclaxTask, error) {
	row := q.db.QueryRow(ctx, pullTaskByID, id)
	var i AnclaxTask
	err := row.Scan(
		&i.ID,
		&i.Attributes,
		&i.Spec,
		&i.Status,
		&i.UniqueTag,
		&i.StartedAt,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.Attempts,
	)
	return &i, err
}

const updateTask = `-- name: UpdateTask :exec
UPDATE anclax.tasks
SET attributes = $2, spec = $3, started_at = $4, updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

type UpdateTaskParams struct {
	ID         int32
	Attributes apigen.TaskAttributes
	Spec       apigen.TaskSpec
	StartedAt  *time.Time
}

func (q *Queries) UpdateTask(ctx context.Context, arg UpdateTaskParams) error {
	_, err := q.db.Exec(ctx, updateTask,
		arg.ID,
		arg.Attributes,
		arg.Spec,
		arg.StartedAt,
	)
	return err
}

const updateTaskStartedAt = `-- name: UpdateTaskStartedAt :exec
UPDATE anclax.tasks
SET started_at = $2, updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

type UpdateTaskStartedAtParams struct {
	ID        int32
	StartedAt *time.Time
}

func (q *Queries) UpdateTaskStartedAt(ctx context.Context, arg UpdateTaskStartedAtParams) error {
	_, err := q.db.Exec(ctx, updateTaskStartedAt, arg.ID, arg.StartedAt)
	return err
}

const updateTaskStatus = `-- name: UpdateTaskStatus :exec
UPDATE anclax.tasks
SET 
    status = $2,
    updated_at = CURRENT_TIMESTAMP
WHERE id = $1
`

type UpdateTaskStatusParams struct {
	ID     int32
	Status string
}

func (q *Queries) UpdateTaskStatus(ctx context.Context, arg UpdateTaskStatusParams) error {
	_, err := q.db.Exec(ctx, updateTaskStatus, arg.ID, arg.Status)
	return err
}
