-- name: GetUserSecretByUserIDAndName :one
SELECT *
FROM user_secrets
WHERE user_id = @user_id AND name = @name;

-- name: GetUserSecretByID :one
SELECT *
FROM user_secrets
WHERE id = @id;

-- name: ListUserSecrets :many
-- Returns metadata only (no value or value_key_id) for the
-- REST API list and get endpoints.
SELECT
    id, user_id, name, description,
    env_name, file_path,
    created_at, updated_at
FROM user_secrets
WHERE user_id = @user_id
ORDER BY name ASC;

-- name: ListUserSecretsWithValues :many
-- Returns all columns including the secret value. Used by the
-- provisioner (build-time injection) and the agent manifest
-- (runtime injection).
SELECT *
FROM user_secrets
WHERE user_id = @user_id
ORDER BY name ASC;

-- name: CreateUserSecret :one
INSERT INTO user_secrets (
    id,
    user_id,
    name,
    description,
    value,
    value_key_id,
    env_name,
    file_path
) VALUES (
    @id,
    @user_id,
    @name,
    @description,
    @value,
    @value_key_id,
    @env_name,
    @file_path
) RETURNING *;

-- name: UpdateUserSecretByUserIDAndName :one
UPDATE user_secrets
SET
    value       = CASE WHEN @update_value::bool THEN @value ELSE value END,
    value_key_id = CASE WHEN @update_value::bool THEN @value_key_id ELSE value_key_id END,
    description = CASE WHEN @update_description::bool THEN @description ELSE description END,
    env_name    = CASE WHEN @update_env_name::bool THEN @env_name ELSE env_name END,
    file_path   = CASE WHEN @update_file_path::bool THEN @file_path ELSE file_path END,
    updated_at  = CURRENT_TIMESTAMP
WHERE user_id = @user_id AND name = @name
RETURNING *;

-- name: DeleteUserSecretByUserIDAndName :one
DELETE FROM user_secrets
WHERE user_id = @user_id AND name = @name
RETURNING *;

-- name: GetUserSecretsTelemetrySummary :one
-- Returns deployment-wide aggregates for the telemetry snapshot.
--
-- The denominator for both user-level counts and the per-user
-- distribution is active non-system users. Specifically:
--
--   * deleted = false: Coder soft-deletes by flipping users.deleted
--     rather than removing rows. The delete_deleted_user_resources()
--     trigger now removes their user_secrets, but soft-deleted users
--     are still excluded here so they don't dilute the percentile
--     distribution as zero-secret entries.
--   * status = 'active': dormant users (no recent activity) and
--     suspended users (explicitly disabled) cannot use secrets, so
--     they shouldn't dilute the percentile distribution as
--     zero-secret entries.
--   * is_system = false: internal subjects like the prebuilds user
--     never use secrets in the normal flow.
--
-- Status transitions move users in and out of this denominator, so a
-- snapshot's UsersWithSecrets can drop without any secret being
-- deleted.
--
-- The percentile distribution is computed across all active non-system
-- users, including those with zero secrets, so the percentiles reflect
-- deployment-wide adoption rather than only the power-user subset.
-- percentile_disc returns an actual integer count from the underlying
-- values rather than interpolating between rows.
WITH active_users AS (
    SELECT id AS user_id
    FROM users
    WHERE deleted = false
      AND is_system = false
      AND status = 'active'::user_status
),
per_user AS (
    SELECT au.user_id, COUNT(us.id)::bigint AS n
    FROM active_users au
    LEFT JOIN user_secrets us ON us.user_id = au.user_id
    GROUP BY au.user_id
),
secrets_filtered AS (
    SELECT us.env_name, us.file_path
    FROM user_secrets us
    JOIN active_users au ON au.user_id = us.user_id
)
SELECT
    COUNT(*) FILTER (WHERE n > 0)::bigint                                                       AS users_with_secrets,
    (SELECT COUNT(*) FROM secrets_filtered)::bigint                                             AS total_secrets,
    (SELECT COUNT(*) FROM secrets_filtered WHERE env_name != '' AND file_path = '' )::bigint    AS env_name_only,
    (SELECT COUNT(*) FROM secrets_filtered WHERE env_name = ''  AND file_path != '')::bigint    AS file_path_only,
    (SELECT COUNT(*) FROM secrets_filtered WHERE env_name != '' AND file_path != '')::bigint    AS both,
    (SELECT COUNT(*) FROM secrets_filtered WHERE env_name = ''  AND file_path = '' )::bigint    AS neither,
    COALESCE(MAX(n), 0)::bigint                                                                 AS secrets_per_user_max,
    COALESCE(percentile_disc(0.25) WITHIN GROUP (ORDER BY n), 0)::bigint                        AS secrets_per_user_p25,
    COALESCE(percentile_disc(0.50) WITHIN GROUP (ORDER BY n), 0)::bigint                        AS secrets_per_user_p50,
    COALESCE(percentile_disc(0.75) WITHIN GROUP (ORDER BY n), 0)::bigint                        AS secrets_per_user_p75,
    COALESCE(percentile_disc(0.90) WITHIN GROUP (ORDER BY n), 0)::bigint                        AS secrets_per_user_p90
FROM per_user;
