// Code generated by sqlc. DO NOT EDIT.
// versions:
//   sqlc v1.30.0
// source: sync.sql

package sqlc

import (
	"context"
	"time"

	"github.com/google/uuid"
	"github.com/stacklok/toolhive-registry-server/internal/db/pgtypes"
)

const bulkInitializeSourceSyncs = `-- name: BulkInitializeSourceSyncs :exec
INSERT INTO registry_sync (
    source_id,
    sync_status,
    error_msg
)
SELECT
    unnest($1::uuid[]),
    unnest($2::sync_status[]),
    unnest($3::text[])
ON CONFLICT (source_id) DO NOTHING
`

type BulkInitializeSourceSyncsParams struct {
	SourceIds    []uuid.UUID  `json:"source_ids"`
	SyncStatuses []SyncStatus `json:"sync_statuses"`
	ErrorMsgs    []string     `json:"error_msgs"`
}

func (q *Queries) BulkInitializeSourceSyncs(ctx context.Context, arg BulkInitializeSourceSyncsParams) error {
	_, err := q.db.Exec(ctx, bulkInitializeSourceSyncs, arg.SourceIds, arg.SyncStatuses, arg.ErrorMsgs)
	return err
}

const getSourceSync = `-- name: GetSourceSync :one
SELECT id,
       source_id,
       sync_status,
       error_msg,
       started_at,
       ended_at,
       attempt_count,
       last_sync_hash,
       last_applied_filter_hash,
       server_count,
       skill_count
FROM registry_sync
WHERE id = $1
`

func (q *Queries) GetSourceSync(ctx context.Context, id uuid.UUID) (RegistrySync, error) {
	row := q.db.QueryRow(ctx, getSourceSync, id)
	var i RegistrySync
	err := row.Scan(
		&i.ID,
		&i.SourceID,
		&i.SyncStatus,
		&i.ErrorMsg,
		&i.StartedAt,
		&i.EndedAt,
		&i.AttemptCount,
		&i.LastSyncHash,
		&i.LastAppliedFilterHash,
		&i.ServerCount,
		&i.SkillCount,
	)
	return i, err
}

const getSourceSyncByName = `-- name: GetSourceSyncByName :one
SELECT rs.id,
       rs.source_id,
       rs.sync_status,
       rs.error_msg,
       rs.started_at,
       rs.ended_at,
       rs.attempt_count,
       rs.last_sync_hash,
       rs.last_applied_filter_hash,
       rs.server_count,
       rs.skill_count
FROM registry_sync rs
INNER JOIN source s ON rs.source_id = s.id
WHERE s.name = $1
`

func (q *Queries) GetSourceSyncByName(ctx context.Context, name string) (RegistrySync, error) {
	row := q.db.QueryRow(ctx, getSourceSyncByName, name)
	var i RegistrySync
	err := row.Scan(
		&i.ID,
		&i.SourceID,
		&i.SyncStatus,
		&i.ErrorMsg,
		&i.StartedAt,
		&i.EndedAt,
		&i.AttemptCount,
		&i.LastSyncHash,
		&i.LastAppliedFilterHash,
		&i.ServerCount,
		&i.SkillCount,
	)
	return i, err
}

const initializeSourceSync = `-- name: InitializeSourceSync :exec
INSERT INTO registry_sync (
    source_id,
    sync_status,
    error_msg
) VALUES (
    (SELECT id FROM source WHERE name = $1),
    $2,
    $3
)
ON CONFLICT (source_id) DO NOTHING
`

type InitializeSourceSyncParams struct {
	Name       string     `json:"name"`
	SyncStatus SyncStatus `json:"sync_status"`
	ErrorMsg   *string    `json:"error_msg"`
}

func (q *Queries) InitializeSourceSync(ctx context.Context, arg InitializeSourceSyncParams) error {
	_, err := q.db.Exec(ctx, initializeSourceSync, arg.Name, arg.SyncStatus, arg.ErrorMsg)
	return err
}

const insertSourceSync = `-- name: InsertSourceSync :one
INSERT INTO registry_sync (
    source_id,
    sync_status,
    error_msg,
    started_at
) VALUES (
    $1,
    $2,
    $3,
    $4
) RETURNING id
`

type InsertSourceSyncParams struct {
	SourceID   *uuid.UUID `json:"source_id"`
	SyncStatus SyncStatus `json:"sync_status"`
	ErrorMsg   *string    `json:"error_msg"`
	StartedAt  *time.Time `json:"started_at"`
}

func (q *Queries) InsertSourceSync(ctx context.Context, arg InsertSourceSyncParams) (uuid.UUID, error) {
	row := q.db.QueryRow(ctx, insertSourceSync,
		arg.SourceID,
		arg.SyncStatus,
		arg.ErrorMsg,
		arg.StartedAt,
	)
	var id uuid.UUID
	err := row.Scan(&id)
	return id, err
}

const listSourceSyncs = `-- name: ListSourceSyncs :many
SELECT s.name,
       rs.id,
       rs.source_id,
       rs.sync_status,
       rs.error_msg,
       rs.started_at,
       rs.ended_at,
       rs.attempt_count,
       rs.last_sync_hash,
       rs.last_applied_filter_hash,
       rs.server_count,
       rs.skill_count,
       s.sync_schedule::interval AS sync_schedule
FROM registry_sync rs
INNER JOIN source s ON rs.source_id = s.id
ORDER BY rs.started_at DESC, s.name ASC
`

type ListSourceSyncsRow struct {
	Name                  string           `json:"name"`
	ID                    uuid.UUID        `json:"id"`
	SourceID              *uuid.UUID       `json:"source_id"`
	SyncStatus            SyncStatus       `json:"sync_status"`
	ErrorMsg              *string          `json:"error_msg"`
	StartedAt             *time.Time       `json:"started_at"`
	EndedAt               *time.Time       `json:"ended_at"`
	AttemptCount          int64            `json:"attempt_count"`
	LastSyncHash          *string          `json:"last_sync_hash"`
	LastAppliedFilterHash *string          `json:"last_applied_filter_hash"`
	ServerCount           int64            `json:"server_count"`
	SkillCount            int64            `json:"skill_count"`
	SyncSchedule          pgtypes.Interval `json:"sync_schedule"`
}

func (q *Queries) ListSourceSyncs(ctx context.Context) ([]ListSourceSyncsRow, error) {
	rows, err := q.db.Query(ctx, listSourceSyncs)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []ListSourceSyncsRow{}
	for rows.Next() {
		var i ListSourceSyncsRow
		if err := rows.Scan(
			&i.Name,
			&i.ID,
			&i.SourceID,
			&i.SyncStatus,
			&i.ErrorMsg,
			&i.StartedAt,
			&i.EndedAt,
			&i.AttemptCount,
			&i.LastSyncHash,
			&i.LastAppliedFilterHash,
			&i.ServerCount,
			&i.SkillCount,
			&i.SyncSchedule,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listSourceSyncsByLastUpdate = `-- name: ListSourceSyncsByLastUpdate :many
SELECT s.name,
       rs.id,
       rs.source_id,
       rs.sync_status,
       rs.error_msg,
       rs.started_at,
       rs.ended_at,
       rs.attempt_count,
       rs.last_sync_hash,
       rs.last_applied_filter_hash,
       rs.server_count,
       rs.skill_count,
       s.sync_schedule::interval AS sync_schedule
FROM registry_sync rs
INNER JOIN source s ON rs.source_id = s.id
WHERE s.syncable = true
  AND (rs.ended_at IS NULL
       OR rs.ended_at + s.sync_schedule::interval <= now())
ORDER BY rs.ended_at ASC NULLS FIRST, s.name ASC
FOR UPDATE OF rs SKIP LOCKED
LIMIT 1
`

type ListSourceSyncsByLastUpdateRow struct {
	Name                  string           `json:"name"`
	ID                    uuid.UUID        `json:"id"`
	SourceID              *uuid.UUID       `json:"source_id"`
	SyncStatus            SyncStatus       `json:"sync_status"`
	ErrorMsg              *string          `json:"error_msg"`
	StartedAt             *time.Time       `json:"started_at"`
	EndedAt               *time.Time       `json:"ended_at"`
	AttemptCount          int64            `json:"attempt_count"`
	LastSyncHash          *string          `json:"last_sync_hash"`
	LastAppliedFilterHash *string          `json:"last_applied_filter_hash"`
	ServerCount           int64            `json:"server_count"`
	SkillCount            int64            `json:"skill_count"`
	SyncSchedule          pgtypes.Interval `json:"sync_schedule"`
}

func (q *Queries) ListSourceSyncsByLastUpdate(ctx context.Context) ([]ListSourceSyncsByLastUpdateRow, error) {
	rows, err := q.db.Query(ctx, listSourceSyncsByLastUpdate)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []ListSourceSyncsByLastUpdateRow{}
	for rows.Next() {
		var i ListSourceSyncsByLastUpdateRow
		if err := rows.Scan(
			&i.Name,
			&i.ID,
			&i.SourceID,
			&i.SyncStatus,
			&i.ErrorMsg,
			&i.StartedAt,
			&i.EndedAt,
			&i.AttemptCount,
			&i.LastSyncHash,
			&i.LastAppliedFilterHash,
			&i.ServerCount,
			&i.SkillCount,
			&i.SyncSchedule,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const updateSourceSync = `-- name: UpdateSourceSync :exec
UPDATE registry_sync SET
    sync_status = $1,
    error_msg = $2,
    ended_at = $3
WHERE id = $4
`

type UpdateSourceSyncParams struct {
	SyncStatus SyncStatus `json:"sync_status"`
	ErrorMsg   *string    `json:"error_msg"`
	EndedAt    *time.Time `json:"ended_at"`
	ID         uuid.UUID  `json:"id"`
}

func (q *Queries) UpdateSourceSync(ctx context.Context, arg UpdateSourceSyncParams) error {
	_, err := q.db.Exec(ctx, updateSourceSync,
		arg.SyncStatus,
		arg.ErrorMsg,
		arg.EndedAt,
		arg.ID,
	)
	return err
}

const updateSourceSyncStatusByName = `-- name: UpdateSourceSyncStatusByName :exec
UPDATE registry_sync
SET sync_status = $1,
    started_at = $2
WHERE source_id = (SELECT id FROM source WHERE name = $3)
`

type UpdateSourceSyncStatusByNameParams struct {
	SyncStatus SyncStatus `json:"sync_status"`
	StartedAt  *time.Time `json:"started_at"`
	Name       string     `json:"name"`
}

func (q *Queries) UpdateSourceSyncStatusByName(ctx context.Context, arg UpdateSourceSyncStatusByNameParams) error {
	_, err := q.db.Exec(ctx, updateSourceSyncStatusByName, arg.SyncStatus, arg.StartedAt, arg.Name)
	return err
}

const upsertSourceSyncByName = `-- name: UpsertSourceSyncByName :exec
INSERT INTO registry_sync (
    source_id,
    sync_status,
    error_msg,
    started_at,
    ended_at,
    attempt_count,
    last_sync_hash,
    last_applied_filter_hash,
    server_count,
    skill_count
) VALUES (
    (SELECT id FROM source WHERE name = $1),
    $2,
    $3,
    $4,
    $5,
    $6,
    $7,
    $8,
    $9,
    $10
)
ON CONFLICT (source_id) DO UPDATE SET
    sync_status = EXCLUDED.sync_status,
    error_msg = EXCLUDED.error_msg,
    started_at = EXCLUDED.started_at,
    ended_at = EXCLUDED.ended_at,
    attempt_count = EXCLUDED.attempt_count,
    last_sync_hash = EXCLUDED.last_sync_hash,
    last_applied_filter_hash = EXCLUDED.last_applied_filter_hash,
    server_count = EXCLUDED.server_count,
    skill_count = EXCLUDED.skill_count
`

type UpsertSourceSyncByNameParams struct {
	Name                  string     `json:"name"`
	SyncStatus            SyncStatus `json:"sync_status"`
	ErrorMsg              *string    `json:"error_msg"`
	StartedAt             *time.Time `json:"started_at"`
	EndedAt               *time.Time `json:"ended_at"`
	AttemptCount          int64      `json:"attempt_count"`
	LastSyncHash          *string    `json:"last_sync_hash"`
	LastAppliedFilterHash *string    `json:"last_applied_filter_hash"`
	ServerCount           int64      `json:"server_count"`
	SkillCount            int64      `json:"skill_count"`
}

func (q *Queries) UpsertSourceSyncByName(ctx context.Context, arg UpsertSourceSyncByNameParams) error {
	_, err := q.db.Exec(ctx, upsertSourceSyncByName,
		arg.Name,
		arg.SyncStatus,
		arg.ErrorMsg,
		arg.StartedAt,
		arg.EndedAt,
		arg.AttemptCount,
		arg.LastSyncHash,
		arg.LastAppliedFilterHash,
		arg.ServerCount,
		arg.SkillCount,
	)
	return err
}
