-- name: ListQueryRequirementValues :many
WITH reqQueries as (
    SELECT q.id as queryId, q.activeVersion, q.type
    FROM requiredQueries as rq
    JOIN queries as q on q.id = rq.requiredQueryId
    WHERE rq.queryId = @queryId
        and @version >= rq.addedVersion
        and (rq.removedVersion is null or @version < rq.removedVersion)
),
codeVersions as (
    SELECT 
        d.id as documentId,
        coalesce(ccv.minCleanVersion, 1) as minCleanVersion,
        coalesce(ccv.minTextVersion, 1) as minTextVersion
    FROM documents as d
    LEFT JOIN collectors as c on c.jobId = d.jobId
    LEFT JOIN collectorCodeVersions as ccv on c.id = ccv.collectorId
        and c.activeVersion >= ccv.addedVersion
        and c.activeVersion < COALESCE(ccv.removedVersion, c.activeVersion)
    WHERE d.id = @documentId
    LIMIT 1
),
latestVersions AS (
    SELECT 
        rq.queryId,
        rq.type,
        r.queryVersion,
        r.cleanVersion,
        r.textVersion,
        ROW_NUMBER() OVER (
            PARTITION BY rq.queryId
            ORDER BY r.cleanVersion DESC, r.textVersion DESC
        ) as rowNumber
    FROM reqQueries as rq
    LEFT JOIN results as r ON rq.queryId = r.queryId
        and r.documentId = @documentId
    JOIN codeVersions as ccv on ccv.documentId = r.documentId
    WHERE r.documentId = @documentId
        and r.queryVersion = rq.activeVersion
        and r.cleanVersion >= ccv.minCleanVersion
        and r.textVersion >= ccv.minTextVersion
)
SELECT lv.queryId, lv.type, r.value
FROM latestVersions as lv
JOIN results as r ON r.queryId = lv.queryId
    and r.documentId = @documentId
    and r.queryVersion = lv.queryVersion
    and r.cleanVersion = lv.cleanVersion
    and r.textVersion = lv.textVersion
    and lv.rowNumber = 1;

-- name: SetResult :exec
INSERT INTO results (queryId, documentId, value, cleanVersion, textVersion, queryVersion) VALUES ($1, $2, $3, $4, $5, $6);

-- name: GetResultValueWithVersion :one
SELECT id, value FROM results WHERE queryId = $1 and queryVersion = $2 and documentId = $3 and cleanVersion >= $4 and textVersion >= $5;

-- name: ListUnsyncedNoDepsQueriesByDocId :many
WITH docs as (
    SELECT id, jobId from documents where id = $1
),
unsyncedQueries AS (
    SELECT DISTINCT dt.queryId, dt.requiredIds, r.value, d.jobID, d.id
        from docs as d
        JOIN collectorQueryDependencyTree as dt on d.jobId = dt.jobId
        JOIN fullActiveCollectors as c on c.id = dt.collectorId
        LEFT JOIN results as r on r.queryId = dt.queryId
            and r.documentId = d.id
            and r.queryVersion = dt.queryVersion
            and r.cleanVersion >= c.minCleanVersion and r.textVersion >= c.minTextVersion
        where r.value is null
)
SELECT DISTINCT queryId FROM unsyncedQueries as baseuq
    WHERE NOT EXISTS (
        SELECT 1 FROM unsyncedQueries as uq WHERE uq.queryId = any(baseuq.requiredIds)
    );
    