-- Copyright (c) Microsoft Corporation.
-- Licensed under the PostgreSQL License.

-- E2E Test: df.http() raises an error at DSL call time when no http Cargo feature
-- is compiled in.
--
-- This test runs in the "http-disabled" phase, which builds pg_durable without any
-- http-allow-* features.  df.http() must raise immediately at SQL call time (before
-- df.start() is ever called), not just at execution time.

-- ============================================================================
-- Test 1: df.http() raises at DSL construction time when HTTP is disabled
-- ============================================================================

DO $$
DECLARE
    caught BOOLEAN := false;
BEGIN
    BEGIN
        -- This call should raise an error immediately — no df.start() needed.
        PERFORM df.http('https://example.com/path', 'GET');
    EXCEPTION WHEN OTHERS THEN
        IF SQLERRM ILIKE '%df.http() is disabled%' THEN
            caught := true;
        ELSE
            RAISE EXCEPTION 'TEST FAILED: unexpected error message: %', SQLERRM;
        END IF;
    END;

    IF NOT caught THEN
        RAISE EXCEPTION 'TEST FAILED: df.http() should raise at DSL time when HTTP is disabled';
    END IF;

    RAISE NOTICE 'TEST PASSED: http_dsl_disabled_raises';
END $$;

-- ============================================================================
-- Test 2: Crafting an HTTP node by passing raw JSON to df.start() bypasses the
-- DSL-time guard but is still blocked at execution time.
--
-- df.start() accepts a serialized Durofut JSON string directly, so a caller
-- can construct an HTTP node without ever touching df.http().  The execution-
-- time defence in execute_http (validate_url_allowlist) must catch this.
-- ============================================================================

CREATE TEMP TABLE _test_http_bypass (instance_id TEXT);

-- Pass a hand-crafted HTTP node JSON straight to df.start().
-- df.start() accepts raw Durofut JSON, so this bypasses the df.http() guard.
INSERT INTO _test_http_bypass
SELECT df.start(
    '{"node_type":"HTTP","query":"{\"url\":\"https://example.com/path\",\"method\":\"GET\",\"body\":null,\"headers\":null,\"timeout_seconds\":5}"}',
    'test-http-bypass-attempt'
);

DO $$
DECLARE
    inst_id     TEXT;
    status      TEXT;
    node_result TEXT;
BEGIN
    SELECT instance_id INTO inst_id FROM _test_http_bypass;

    -- Wait up to 30 s; the request must fail (not complete or time out).
    SELECT df.await_instance(inst_id, 30) INTO status;

    IF status != 'failed' THEN
        RAISE EXCEPTION 'TEST FAILED: expected status = failed, got %', status;
    END IF;

    -- The node result should contain the execution-time block message.
    SELECT result::text INTO node_result
    FROM df.nodes
    WHERE instance_id = inst_id AND node_type = 'HTTP';

    IF node_result IS NULL OR node_result NOT ILIKE '%outbound HTTP requests are disabled%' THEN
        RAISE EXCEPTION
            'TEST FAILED: expected "outbound HTTP requests are disabled" in node result, got: %',
            node_result;
    END IF;

    RAISE NOTICE 'TEST PASSED: http_execution_blocked_without_feature';
END $$;

DROP TABLE _test_http_bypass;

SELECT 'TEST PASSED' AS result;
