-- name: GetActiveQueryConfig :one
SELECT config FROM queryCurrentConfigs where queryId = $1;

-- name: GetQuery :one
SELECT * FROM fullActiveQueries WHERE id = $1;

-- name: GetQueryWithVersion :one
WITH query as (
    SELECT id, type FROM queries WHERE id = @id
),
config as (
SELECT c.queryId, c.config
    FROM query AS q
    LEFT JOIN queryConfigs AS c ON q.id = c.queryId
        and isInVersion(@version, c.addedVersion, c.removedVersion)
),
requiredIds as (
    SELECT r.queryId,
    coalesce(
        ARRAY_AGG(DISTINCT r.requiredQueryId)
        FILTER (WHERE r.requiredQueryId != '00000000-0000-0000-0000-000000000000')::uuid[],
        array[]::uuid[]
    )::uuid[] as requiredIds
    FROM query AS q
    LEFT JOIN requiredQueries AS r ON q.id = r.queryId
        and isInVersion(@version, r.addedVersion, r.removedVersion)
    GROUP BY r.queryId
)
SELECT DISTINCT q.id, q.type,
    av.activeVersion,
    lv.latestVersion, c.config,
    r.requiredIds
    FROM query AS q
    JOIN queryCurrentActiveVersions as av on q.id = av.queryId
    JOIN queryLatestVersions as lv on lv.queryId = q.id
    LEFT JOIN config AS c ON q.id = c.queryId
    LEFT JOIN requiredIds AS r ON q.id = r.queryId;

-- name: ListQueries :many
SELECT * FROM fullActiveQueries;

-- name: ListQueriesById :many
SELECT * FROM fullActiveQueries WHERE id = any($1);

-- name: CreateQuery :one
INSERT INTO queries (type) VALUES ($1) RETURNING id;

-- name: AddLatestQueryVersion :one
INSERT INTO queryVersions (queryId) VALUES ($1) RETURNING id;

-- name: AddActiveQueryVersion :exec
INSERT INTO queryActiveVersions (queryId, versionId) VALUES ($1, $2);

-- name: AddRequiredQuery :exec
INSERT INTO requiredQueries (queryId, requiredQueryId, addedVersion) VALUES ($1, $2, $3);

-- name: RemoveRequiredQuery :exec
UPDATE requiredQueries SET removedVersion = $1 WHERE requiredQueryId = $2 and queryId = $3 and removedVersion is null;

-- name: SetQueryConfig :exec
INSERT INTO queryConfigs (queryId, config, addedVersion) VALUES ($1, $2, $3);

-- name: AllQueriesExist :one
SELECT COUNT(*) = COUNT(DISTINCT id) AS all_exist
    FROM unnest($1::uuid[]) AS input_id
    LEFT JOIN queries ON input_id = queries.id;

-- name: IsQueryInDependencyTree :one
SELECT EXISTS (
    SELECT 1 FROM queryActiveDependencies
    WHERE id = any(@requiredQueryIds)
    and requiredQueryId = @queryId
    or @queryId = any(@requiredQueryIds)
);

-- name: ListQueryDirectDependentsByDocumentID :many
WITH doc AS (
    SELECT id, clientId FROM documents where id = @documentId
)
SELECT dt.queryId
    FROM doc as d
    JOIN collectorQueryDependencyTree as dt
        on d.clientId = dt.clientId
        and @queryId = any(dt.requiredIds);

-- name: ListQueryClientIDs :many
SELECT clientId FROM collectorQueryDependencyTree WHERE queryId = $1;
