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

package sqlc

import (
	"context"
	"time"

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

const bulkUpsertConfigSources = `-- name: BulkUpsertConfigSources :many
INSERT INTO source (
    name,
    creation_type,
    source_type,
    source_config,
    filter_config,
    sync_schedule,
    syncable,
    claims,
    created_at,
    updated_at
)
SELECT
    unnest($1::text[]),
    'CONFIG',
    unnest($2::text[]),
    unnest($3::jsonb[]),
    unnest($4::jsonb[]),
    unnest($5::interval[]),
    unnest($6::boolean[]),
    unnest($7::jsonb[]),
    unnest($8::timestamp with time zone[]),
    unnest($9::timestamp with time zone[])
ON CONFLICT (name) DO UPDATE SET
    source_type = EXCLUDED.source_type,
    source_config = EXCLUDED.source_config,
    filter_config = EXCLUDED.filter_config,
    sync_schedule = EXCLUDED.sync_schedule,
    syncable = EXCLUDED.syncable,
    claims = EXCLUDED.claims,
    updated_at = EXCLUDED.updated_at
WHERE source.creation_type = 'CONFIG'
RETURNING id, name
`

type BulkUpsertConfigSourcesParams struct {
	Names         []string           `json:"names"`
	SourceTypes   []string           `json:"source_types"`
	SourceConfigs [][]byte           `json:"source_configs"`
	FilterConfigs [][]byte           `json:"filter_configs"`
	SyncSchedules []pgtypes.Interval `json:"sync_schedules"`
	Syncables     []bool             `json:"syncables"`
	Claims        [][]byte           `json:"claims"`
	CreatedAts    []time.Time        `json:"created_ats"`
	UpdatedAts    []time.Time        `json:"updated_ats"`
}

type BulkUpsertConfigSourcesRow struct {
	ID   uuid.UUID `json:"id"`
	Name string    `json:"name"`
}

// Bulk insert or update CONFIG sources (only updates existing CONFIG sources)
func (q *Queries) BulkUpsertConfigSources(ctx context.Context, arg BulkUpsertConfigSourcesParams) ([]BulkUpsertConfigSourcesRow, error) {
	rows, err := q.db.Query(ctx, bulkUpsertConfigSources,
		arg.Names,
		arg.SourceTypes,
		arg.SourceConfigs,
		arg.FilterConfigs,
		arg.SyncSchedules,
		arg.Syncables,
		arg.Claims,
		arg.CreatedAts,
		arg.UpdatedAts,
	)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []BulkUpsertConfigSourcesRow{}
	for rows.Next() {
		var i BulkUpsertConfigSourcesRow
		if err := rows.Scan(&i.ID, &i.Name); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const deleteConfigSourcesNotInList = `-- name: DeleteConfigSourcesNotInList :exec
DELETE FROM source
WHERE id NOT IN (SELECT unnest($1::uuid[]))
  AND creation_type = 'CONFIG'
`

// Delete CONFIG sources not in the provided list (for config file sync)
func (q *Queries) DeleteConfigSourcesNotInList(ctx context.Context, ids []uuid.UUID) error {
	_, err := q.db.Exec(ctx, deleteConfigSourcesNotInList, ids)
	return err
}

const deleteSource = `-- name: DeleteSource :execrows
DELETE FROM source
WHERE name = $1
`

// Delete a source by name. Go callers guard against deleting wrong creation_type.
func (q *Queries) DeleteSource(ctx context.Context, name string) (int64, error) {
	result, err := q.db.Exec(ctx, deleteSource, name)
	if err != nil {
		return 0, err
	}
	return result.RowsAffected(), nil
}

const getAPISourcesByNames = `-- name: GetAPISourcesByNames :many
SELECT id,
       name,
       creation_type,
       source_type,
       source_config,
       filter_config,
       sync_schedule,
       claims,
       created_at,
       updated_at
FROM source
WHERE name = ANY($1::text[])
  AND creation_type = 'API'
`

type GetAPISourcesByNamesRow struct {
	ID           uuid.UUID        `json:"id"`
	Name         string           `json:"name"`
	CreationType CreationType     `json:"creation_type"`
	SourceType   string           `json:"source_type"`
	SourceConfig []byte           `json:"source_config"`
	FilterConfig []byte           `json:"filter_config"`
	SyncSchedule pgtypes.Interval `json:"sync_schedule"`
	Claims       []byte           `json:"claims"`
	CreatedAt    *time.Time       `json:"created_at"`
	UpdatedAt    *time.Time       `json:"updated_at"`
}

func (q *Queries) GetAPISourcesByNames(ctx context.Context, names []string) ([]GetAPISourcesByNamesRow, error) {
	rows, err := q.db.Query(ctx, getAPISourcesByNames, names)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetAPISourcesByNamesRow{}
	for rows.Next() {
		var i GetAPISourcesByNamesRow
		if err := rows.Scan(
			&i.ID,
			&i.Name,
			&i.CreationType,
			&i.SourceType,
			&i.SourceConfig,
			&i.FilterConfig,
			&i.SyncSchedule,
			&i.Claims,
			&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 getManagedSources = `-- name: GetManagedSources :many
SELECT id, name, source_type, creation_type, claims, created_at, updated_at
FROM source WHERE source_type = 'managed'
`

type GetManagedSourcesRow struct {
	ID           uuid.UUID    `json:"id"`
	Name         string       `json:"name"`
	SourceType   string       `json:"source_type"`
	CreationType CreationType `json:"creation_type"`
	Claims       []byte       `json:"claims"`
	CreatedAt    *time.Time   `json:"created_at"`
	UpdatedAt    *time.Time   `json:"updated_at"`
}

func (q *Queries) GetManagedSources(ctx context.Context) ([]GetManagedSourcesRow, error) {
	rows, err := q.db.Query(ctx, getManagedSources)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []GetManagedSourcesRow{}
	for rows.Next() {
		var i GetManagedSourcesRow
		if err := rows.Scan(
			&i.ID,
			&i.Name,
			&i.SourceType,
			&i.CreationType,
			&i.Claims,
			&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 getSource = `-- name: GetSource :one
SELECT id,
       name,
       creation_type,
       source_type,
       source_config,
       filter_config,
       sync_schedule,
       claims,
       created_at,
       updated_at
  FROM source
 WHERE id = $1
`

type GetSourceRow struct {
	ID           uuid.UUID        `json:"id"`
	Name         string           `json:"name"`
	CreationType CreationType     `json:"creation_type"`
	SourceType   string           `json:"source_type"`
	SourceConfig []byte           `json:"source_config"`
	FilterConfig []byte           `json:"filter_config"`
	SyncSchedule pgtypes.Interval `json:"sync_schedule"`
	Claims       []byte           `json:"claims"`
	CreatedAt    *time.Time       `json:"created_at"`
	UpdatedAt    *time.Time       `json:"updated_at"`
}

func (q *Queries) GetSource(ctx context.Context, id uuid.UUID) (GetSourceRow, error) {
	row := q.db.QueryRow(ctx, getSource, id)
	var i GetSourceRow
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.CreationType,
		&i.SourceType,
		&i.SourceConfig,
		&i.FilterConfig,
		&i.SyncSchedule,
		&i.Claims,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const getSourceByName = `-- name: GetSourceByName :one
SELECT id,
       name,
       creation_type,
       source_type,
       source_config,
       filter_config,
       sync_schedule,
       claims,
       created_at,
       updated_at
  FROM source
 WHERE name = $1
`

type GetSourceByNameRow struct {
	ID           uuid.UUID        `json:"id"`
	Name         string           `json:"name"`
	CreationType CreationType     `json:"creation_type"`
	SourceType   string           `json:"source_type"`
	SourceConfig []byte           `json:"source_config"`
	FilterConfig []byte           `json:"filter_config"`
	SyncSchedule pgtypes.Interval `json:"sync_schedule"`
	Claims       []byte           `json:"claims"`
	CreatedAt    *time.Time       `json:"created_at"`
	UpdatedAt    *time.Time       `json:"updated_at"`
}

func (q *Queries) GetSourceByName(ctx context.Context, name string) (GetSourceByNameRow, error) {
	row := q.db.QueryRow(ctx, getSourceByName, name)
	var i GetSourceByNameRow
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.CreationType,
		&i.SourceType,
		&i.SourceConfig,
		&i.FilterConfig,
		&i.SyncSchedule,
		&i.Claims,
		&i.CreatedAt,
		&i.UpdatedAt,
	)
	return i, err
}

const insertSource = `-- name: InsertSource :one

INSERT INTO source (
    name,
    creation_type,
    source_type,
    source_config,
    filter_config,
    sync_schedule,
    syncable,
    claims,
    created_at,
    updated_at
) VALUES (
    $1,
    $2,
    $3,
    $4,
    $5,
    $6,
    $7,
    $8,
    $9,
    $10
) RETURNING id, name, created_at, updated_at, creation_type, sync_schedule, source_type, source_config, filter_config, syncable, claims
`

type InsertSourceParams struct {
	Name         string           `json:"name"`
	CreationType CreationType     `json:"creation_type"`
	SourceType   string           `json:"source_type"`
	SourceConfig []byte           `json:"source_config"`
	FilterConfig []byte           `json:"filter_config"`
	SyncSchedule pgtypes.Interval `json:"sync_schedule"`
	Syncable     bool             `json:"syncable"`
	Claims       []byte           `json:"claims"`
	CreatedAt    *time.Time       `json:"created_at"`
	UpdatedAt    *time.Time       `json:"updated_at"`
}

// ============================================================================
// Source Queries (unified, creation_type guards are in Go)
// ============================================================================
// Insert a new source with full configuration. creation_type is passed as a parameter.
func (q *Queries) InsertSource(ctx context.Context, arg InsertSourceParams) (Source, error) {
	row := q.db.QueryRow(ctx, insertSource,
		arg.Name,
		arg.CreationType,
		arg.SourceType,
		arg.SourceConfig,
		arg.FilterConfig,
		arg.SyncSchedule,
		arg.Syncable,
		arg.Claims,
		arg.CreatedAt,
		arg.UpdatedAt,
	)
	var i Source
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.CreationType,
		&i.SyncSchedule,
		&i.SourceType,
		&i.SourceConfig,
		&i.FilterConfig,
		&i.Syncable,
		&i.Claims,
	)
	return i, err
}

const listAllSourceNames = `-- name: ListAllSourceNames :many
SELECT name FROM source ORDER BY name
`

func (q *Queries) ListAllSourceNames(ctx context.Context) ([]string, error) {
	rows, err := q.db.Query(ctx, listAllSourceNames)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []string{}
	for rows.Next() {
		var name string
		if err := rows.Scan(&name); err != nil {
			return nil, err
		}
		items = append(items, name)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const listSources = `-- name: ListSources :many
SELECT id,
       name,
       creation_type,
       source_type,
       source_config,
       filter_config,
       sync_schedule,
       claims,
       created_at,
       updated_at
  FROM source
 WHERE ($1::timestamp with time zone IS NULL OR created_at > $1)
   AND ($2::timestamp with time zone IS NULL OR created_at < $2)
 ORDER BY
  -- next page sorting
  CASE WHEN $1::timestamp with time zone IS NULL THEN created_at END ASC,
  CASE WHEN $1::timestamp with time zone IS NULL THEN name END ASC,
  -- previous page sorting
  CASE WHEN $2::timestamp with time zone IS NULL THEN created_at END DESC,
  CASE WHEN $2::timestamp with time zone IS NULL THEN name END DESC
 LIMIT $3::bigint
`

type ListSourcesParams struct {
	Next *time.Time `json:"next"`
	Prev *time.Time `json:"prev"`
	Size int64      `json:"size"`
}

type ListSourcesRow struct {
	ID           uuid.UUID        `json:"id"`
	Name         string           `json:"name"`
	CreationType CreationType     `json:"creation_type"`
	SourceType   string           `json:"source_type"`
	SourceConfig []byte           `json:"source_config"`
	FilterConfig []byte           `json:"filter_config"`
	SyncSchedule pgtypes.Interval `json:"sync_schedule"`
	Claims       []byte           `json:"claims"`
	CreatedAt    *time.Time       `json:"created_at"`
	UpdatedAt    *time.Time       `json:"updated_at"`
}

func (q *Queries) ListSources(ctx context.Context, arg ListSourcesParams) ([]ListSourcesRow, error) {
	rows, err := q.db.Query(ctx, listSources, arg.Next, arg.Prev, arg.Size)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	items := []ListSourcesRow{}
	for rows.Next() {
		var i ListSourcesRow
		if err := rows.Scan(
			&i.ID,
			&i.Name,
			&i.CreationType,
			&i.SourceType,
			&i.SourceConfig,
			&i.FilterConfig,
			&i.SyncSchedule,
			&i.Claims,
			&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 updateSource = `-- name: UpdateSource :one
UPDATE source SET
    source_type = $1,
    source_config = $2,
    filter_config = $3,
    sync_schedule = $4,
    syncable = $5,
    claims = $6,
    updated_at = $7
WHERE name = $8
RETURNING id, name, created_at, updated_at, creation_type, sync_schedule, source_type, source_config, filter_config, syncable, claims
`

type UpdateSourceParams struct {
	SourceType   string           `json:"source_type"`
	SourceConfig []byte           `json:"source_config"`
	FilterConfig []byte           `json:"filter_config"`
	SyncSchedule pgtypes.Interval `json:"sync_schedule"`
	Syncable     bool             `json:"syncable"`
	Claims       []byte           `json:"claims"`
	UpdatedAt    *time.Time       `json:"updated_at"`
	Name         string           `json:"name"`
}

// Update an existing source. Go callers guard against modifying wrong creation_type.
func (q *Queries) UpdateSource(ctx context.Context, arg UpdateSourceParams) (Source, error) {
	row := q.db.QueryRow(ctx, updateSource,
		arg.SourceType,
		arg.SourceConfig,
		arg.FilterConfig,
		arg.SyncSchedule,
		arg.Syncable,
		arg.Claims,
		arg.UpdatedAt,
		arg.Name,
	)
	var i Source
	err := row.Scan(
		&i.ID,
		&i.Name,
		&i.CreatedAt,
		&i.UpdatedAt,
		&i.CreationType,
		&i.SyncSchedule,
		&i.SourceType,
		&i.SourceConfig,
		&i.FilterConfig,
		&i.Syncable,
		&i.Claims,
	)
	return i, err
}

const upsertSource = `-- name: UpsertSource :one

INSERT INTO source (
    name,
    creation_type,
    source_type,
    source_config,
    filter_config,
    sync_schedule,
    syncable,
    claims,
    created_at,
    updated_at
) VALUES (
    $1,
    $2,
    $3,
    $4,
    $5,
    $6,
    $7,
    $8,
    $9,
    $10
)
ON CONFLICT (name) DO UPDATE SET
    source_type = EXCLUDED.source_type,
    source_config = EXCLUDED.source_config,
    filter_config = EXCLUDED.filter_config,
    sync_schedule = EXCLUDED.sync_schedule,
    syncable = EXCLUDED.syncable,
    claims = EXCLUDED.claims,
    updated_at = EXCLUDED.updated_at
RETURNING id
`

type UpsertSourceParams struct {
	Name         string           `json:"name"`
	CreationType CreationType     `json:"creation_type"`
	SourceType   string           `json:"source_type"`
	SourceConfig []byte           `json:"source_config"`
	FilterConfig []byte           `json:"filter_config"`
	SyncSchedule pgtypes.Interval `json:"sync_schedule"`
	Syncable     bool             `json:"syncable"`
	Claims       []byte           `json:"claims"`
	CreatedAt    *time.Time       `json:"created_at"`
	UpdatedAt    *time.Time       `json:"updated_at"`
}

// ============================================================================
// CONFIG Source Queries (only operate on creation_type='CONFIG')
// ============================================================================
// Insert or update a source. The creation_type is passed as a parameter.
// Business logic in Go guards against cross-type overwrites.
func (q *Queries) UpsertSource(ctx context.Context, arg UpsertSourceParams) (uuid.UUID, error) {
	row := q.db.QueryRow(ctx, upsertSource,
		arg.Name,
		arg.CreationType,
		arg.SourceType,
		arg.SourceConfig,
		arg.FilterConfig,
		arg.SyncSchedule,
		arg.Syncable,
		arg.Claims,
		arg.CreatedAt,
		arg.UpdatedAt,
	)
	var id uuid.UUID
	err := row.Scan(&id)
	return id, err
}
