-- broker_get function
-- Fetches the next job from the queue for a given queue number
-- Returns: p_retval (0=success, >0=error), p_errmsg (error message), p_job_id (job ID if found)

CREATE OR REPLACE FUNCTION broker_get(
    p_queue_number INTEGER,
    p_instance_id BIGINT DEFAULT NULL,
    OUT p_retval INTEGER,
    OUT p_errmsg TEXT,
    OUT p_job_id BIGINT
)
RETURNS RECORD
LANGUAGE plpgsql
AS $$
DECLARE
    v_job_record RECORD;
BEGIN
    p_retval := 0;
    p_errmsg := '';
    p_job_id := NULL;

    -- Validate queue number
    IF p_queue_number IS NULL OR p_queue_number <= 0 THEN
        p_retval := 1;
        p_errmsg := 'Invalid queue number';
        RETURN;
    END IF;

    -- Find and lock the next pending job for this queue
    -- Uses SKIP LOCKED to avoid blocking on jobs being processed by other workers
    -- Skip jobs with pending dependencies
    SELECT id_broker_jobs, job_name, job_priority, execute_str
    INTO v_job_record
    FROM broker_jobs
    WHERE job_queue = p_queue_number
      AND complete_status = 0  -- pending
      AND (
        depends_on IS NULL  -- no dependencies
        OR depends_on = '{}'  -- empty dependencies
        OR NOT EXISTS (  -- all dependencies completed
          SELECT 1
          FROM broker_jobs dep
          WHERE dep.job_name = ANY(broker_jobs.depends_on)
            AND dep.complete_status = 0  -- pending dependency
        )
      )
    ORDER BY job_priority DESC, created_at ASC
    LIMIT 1
    FOR UPDATE SKIP LOCKED;

    -- If no job found, return success with NULL job_id
    IF NOT FOUND THEN
        RETURN;
    END IF;

    -- Update job status to running
    UPDATE broker_jobs
    SET complete_status = 1,  -- running
        started_at = NOW(),
        rid_broker_queueinstance = p_instance_id,
        updated_at = NOW()
    WHERE id_broker_jobs = v_job_record.id_broker_jobs;

    -- Return the job ID
    p_job_id := v_job_record.id_broker_jobs;

EXCEPTION
    WHEN OTHERS THEN
        p_retval := 2;
        p_errmsg := SQLERRM;
        RAISE WARNING 'broker_get error: %', SQLERRM;
END;
$$;

-- Comments
COMMENT ON FUNCTION broker_get IS 'Fetches the next pending job from the specified queue';
