-- name: UpsertNode :one
INSERT INTO nodes (id, display_name, multiaddrs, rpc_url, status)
VALUES ($1, $2, $3, $4, 'up')
ON CONFLICT (id) DO UPDATE
    SET display_name = EXCLUDED.display_name,
        multiaddrs   = EXCLUDED.multiaddrs,
        rpc_url      = EXCLUDED.rpc_url,
        status       = CASE WHEN nodes.status = 'drained' THEN 'drained' ELSE 'up' END,
        last_seen_at = now()
RETURNING *;

-- name: GetNode :one
SELECT * FROM nodes WHERE id = $1;

-- name: ListLiveNodes :many
SELECT * FROM nodes WHERE status = 'up' ORDER BY id;

-- name: ListAllNodes :many
SELECT * FROM nodes ORDER BY id;

-- name: TouchNodeHeartbeat :exec
UPDATE nodes SET last_seen_at = now() WHERE id = $1;

-- name: MarkNodeDown :exec
UPDATE nodes SET status = 'down' WHERE id = $1 AND status = 'up';

-- name: DrainNode :exec
UPDATE nodes SET status = 'drained' WHERE id = $1;

-- name: UncordonNode :exec
UPDATE nodes SET status = 'up' WHERE id = $1 AND status = 'drained';

-- name: MarkStaleNodesDown :many
UPDATE nodes
SET status = 'down'
WHERE status = 'up' AND last_seen_at < (now() - make_interval(secs => $1))
RETURNING id;
