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

package dbq

import (
	"context"

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

const deleteOtherSessionsForUser = `-- name: DeleteOtherSessionsForUser :execrows
DELETE FROM sessions WHERE user_id = $1 AND id <> $2
`

type DeleteOtherSessionsForUserParams struct {
	UserID pgtype.UUID
	ID     pgtype.UUID
}

// "Log out everywhere else." Excludes the caller's own session so the action
// doesn't log them out of the page they just used to invoke it.
func (q *Queries) DeleteOtherSessionsForUser(ctx context.Context, arg DeleteOtherSessionsForUserParams) (int64, error) {
	result, err := q.db.Exec(ctx, deleteOtherSessionsForUser, arg.UserID, arg.ID)
	if err != nil {
		return 0, err
	}
	return result.RowsAffected(), nil
}

const deleteSession = `-- name: DeleteSession :exec
DELETE FROM sessions WHERE id = $1
`

func (q *Queries) DeleteSession(ctx context.Context, id pgtype.UUID) error {
	_, err := q.db.Exec(ctx, deleteSession, id)
	return err
}

const deleteSessionByTokenHash = `-- name: DeleteSessionByTokenHash :exec
DELETE FROM sessions WHERE token_hash = $1
`

func (q *Queries) DeleteSessionByTokenHash(ctx context.Context, tokenHash []byte) error {
	_, err := q.db.Exec(ctx, deleteSessionByTokenHash, tokenHash)
	return err
}

const deleteSessionForUser = `-- name: DeleteSessionForUser :execrows
DELETE FROM sessions WHERE id = $1 AND user_id = $2
`

type DeleteSessionForUserParams struct {
	ID     pgtype.UUID
	UserID pgtype.UUID
}

// Scoped by user_id, not just id (rule #47). Keyed on the id alone, any
// household member could revoke another member's session by guessing a uuid.
// execrows lets the handler answer 404 rather than a false 204 when the row
// isn't theirs.
func (q *Queries) DeleteSessionForUser(ctx context.Context, arg DeleteSessionForUserParams) (int64, error) {
	result, err := q.db.Exec(ctx, deleteSessionForUser, arg.ID, arg.UserID)
	if err != nil {
		return 0, err
	}
	return result.RowsAffected(), nil
}

const getSessionByTokenHash = `-- name: GetSessionByTokenHash :one
SELECT id, user_id, token_hash, user_agent, created_at, last_seen_at, created_ip, last_ip FROM sessions WHERE token_hash = $1
`

func (q *Queries) GetSessionByTokenHash(ctx context.Context, tokenHash []byte) (Session, error) {
	row := q.db.QueryRow(ctx, getSessionByTokenHash, tokenHash)
	var i Session
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.TokenHash,
		&i.UserAgent,
		&i.CreatedAt,
		&i.LastSeenAt,
		&i.CreatedIp,
		&i.LastIp,
	)
	return i, err
}

const insertSession = `-- name: InsertSession :one
INSERT INTO sessions (user_id, token_hash, user_agent, created_ip, last_ip)
VALUES ($1, $2, $3, $4, $4)
RETURNING id, user_id, token_hash, user_agent, created_at, last_seen_at, created_ip, last_ip
`

type InsertSessionParams struct {
	UserID    pgtype.UUID
	TokenHash []byte
	UserAgent string
	Ip        string
}

// created_ip and last_ip start equal: at issue time the origin IS the current
// location. They diverge as the session is used from elsewhere, which is what
// makes a stolen token visible in the active-sessions surface.
func (q *Queries) InsertSession(ctx context.Context, arg InsertSessionParams) (Session, error) {
	row := q.db.QueryRow(ctx, insertSession,
		arg.UserID,
		arg.TokenHash,
		arg.UserAgent,
		arg.Ip,
	)
	var i Session
	err := row.Scan(
		&i.ID,
		&i.UserID,
		&i.TokenHash,
		&i.UserAgent,
		&i.CreatedAt,
		&i.LastSeenAt,
		&i.CreatedIp,
		&i.LastIp,
	)
	return i, err
}

const listSessionsForUser = `-- name: ListSessionsForUser :many
SELECT id, user_id, token_hash, user_agent, created_at, last_seen_at, created_ip, last_ip FROM sessions WHERE user_id = $1 ORDER BY last_seen_at DESC
`

// Most-recently-active first: the row a user is most likely to act on is the
// one that moved last, and an unfamiliar entry at the top is the alarm.
func (q *Queries) ListSessionsForUser(ctx context.Context, userID pgtype.UUID) ([]Session, error) {
	rows, err := q.db.Query(ctx, listSessionsForUser, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	var items []Session
	for rows.Next() {
		var i Session
		if err := rows.Scan(
			&i.ID,
			&i.UserID,
			&i.TokenHash,
			&i.UserAgent,
			&i.CreatedAt,
			&i.LastSeenAt,
			&i.CreatedIp,
			&i.LastIp,
		); err != nil {
			return nil, err
		}
		items = append(items, i)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}
	return items, nil
}

const touchSessionLastSeen = `-- name: TouchSessionLastSeen :exec
UPDATE sessions SET last_seen_at = now(), last_ip = $2 WHERE id = $1
`

type TouchSessionLastSeenParams struct {
	ID     pgtype.UUID
	LastIp string
}

func (q *Queries) TouchSessionLastSeen(ctx context.Context, arg TouchSessionLastSeenParams) error {
	_, err := q.db.Exec(ctx, touchSessionLastSeen, arg.ID, arg.LastIp)
	return err
}
