-- used for backend automated testing
-- https://docs.rs/sqlx/latest/sqlx/attr.test.html

INSERT INTO workspace
            (id,               name,             owner)
     VALUES ('test-workspace', 'test-workspace', 'test-user');

INSERT INTO usr(workspace_id, email, username, is_admin, role) VALUES
	('test-workspace', 'test@windmill.dev', 'test-user', true, 'Admin');

INSERT INTO workspace_key(workspace_id, kind, key) VALUES
	('test-workspace', 'cloud', 'test-key');


INSERT INTO workspace_settings (workspace_id) VALUES
	('test-workspace');

insert INTO token(token, email, label, super_admin) VALUES ('SECRET_TOKEN', 'test@windmill.dev', 'test token', true);

GRANT ALL PRIVILEGES ON TABLE workspace_key TO windmill_admin;
GRANT ALL PRIVILEGES ON TABLE workspace_key TO windmill_user;

CREATE FUNCTION "notify_insert_on_completed_job" ()
RETURNS TRIGGER AS $$
BEGIN
    PERFORM pg_notify('completed', NEW.id::text);
    RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;

  CREATE TRIGGER "notify_insert_on_completed_job"
 AFTER INSERT ON "v2_job_completed"
    FOR EACH ROW
EXECUTE FUNCTION "notify_insert_on_completed_job" ();


CREATE FUNCTION "notify_queue" ()
RETURNS TRIGGER AS $$
BEGIN
    PERFORM pg_notify('queued', NEW.id::text);
    RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;

  CREATE TRIGGER "notify_queue_after_insert"
 AFTER INSERT ON "v2_job_queue"
    FOR EACH ROW
EXECUTE FUNCTION "notify_queue" ();

  CREATE TRIGGER "notify_queue_after_flow_status_update"
 AFTER UPDATE ON "v2_job_status"
    FOR EACH ROW
            WHEN (NEW.flow_status IS DISTINCT FROM OLD.flow_status)
EXECUTE FUNCTION "notify_queue" ();

-- TODO(uael): remove before phase 4
CREATE OR REPLACE FUNCTION zzz_v2_job_queue_integrity_check() RETURNS TRIGGER AS $$
DECLARE job v2_job;
DECLARE job_runtime v2_job_runtime;
DECLARE job_status v2_job_status;
BEGIN
    IF (OLD.canceled_by IS NOT NULL) IS DISTINCT FROM OLD.__canceled THEN
        RAISE EXCEPTION 'canceled mismatch';
    END IF;
    -- v2_job:
    SELECT * INTO job FROM v2_job WHERE id = OLD.id;
    IF job.tag IS DISTINCT FROM OLD.tag THEN
        RAISE EXCEPTION 'tag mismatch';
    END IF;
    IF job.workspace_id IS DISTINCT FROM OLD.workspace_id THEN
        RAISE EXCEPTION 'workspace_id mismatch';
    END IF;
    IF job.created_at IS DISTINCT FROM OLD.created_at THEN
        RAISE EXCEPTION 'created_at mismatch';
    END IF;
    IF job.created_by IS DISTINCT FROM OLD.__created_by THEN
        RAISE EXCEPTION 'created_by mismatch';
    END IF;
    IF job.permissioned_as IS DISTINCT FROM OLD.__permissioned_as THEN
        RAISE EXCEPTION 'permissioned_as mismatch';
    END IF;
    IF job.permissioned_as_email IS DISTINCT FROM OLD.__email THEN
        RAISE EXCEPTION 'permissioned_as_email mismatch';
    END IF;
    IF job.kind IS DISTINCT FROM OLD.__job_kind THEN
        RAISE EXCEPTION 'kind mismatch';
    END IF;
    IF job.runnable_id IS DISTINCT FROM OLD.__script_hash THEN
        RAISE EXCEPTION 'runnable_id mismatch';
    END IF;
    IF job.runnable_path IS DISTINCT FROM OLD.__script_path THEN
        RAISE EXCEPTION 'runnable_path mismatch';
    END IF;
    IF job.parent_job IS DISTINCT FROM OLD.__parent_job THEN
        RAISE EXCEPTION 'parent_job mismatch';
    END IF;
    IF job.script_lang IS DISTINCT FROM OLD.__language THEN
        RAISE EXCEPTION 'script_lang mismatch';
    END IF;
    IF job.script_entrypoint_override IS DISTINCT FROM NULLIF(OLD.__args->>'_ENTRYPOINT_OVERRIDE', '__WM_PREPROCESSOR')
        AND OLD.__args->>'reason' IS DISTINCT FROM 'PREPROCESSOR_ARGS_ARE_DISCARDED'
    THEN
        RAISE EXCEPTION 'script_entrypoint_override mismatch';
    END IF;
    IF job.flow_step_id IS DISTINCT FROM OLD.__flow_step_id THEN
        RAISE EXCEPTION 'flow_step_id mismatch';
    END IF;
    IF (job.flow_step_id IS NOT NULL) IS DISTINCT FROM OLD.__is_flow_step THEN
        RAISE EXCEPTION 'is_flow_step mismatch';
    END IF;
    IF job.flow_innermost_root_job IS DISTINCT FROM OLD.__root_job THEN
        RAISE EXCEPTION 'flow_innermost_root_job mismatch';
    END IF;
    IF job.trigger IS DISTINCT FROM OLD.__schedule_path THEN
        RAISE EXCEPTION 'trigger mismatch';
    END IF;
    IF job.same_worker IS DISTINCT FROM OLD.__same_worker THEN
        RAISE EXCEPTION 'same_worker mismatch';
    END IF;
    IF job.visible_to_owner IS DISTINCT FROM OLD.__visible_to_owner THEN
        RAISE EXCEPTION 'visible_to_owner mismatch';
    END IF;
    IF job.concurrent_limit IS DISTINCT FROM OLD.__concurrent_limit THEN
        RAISE EXCEPTION 'concurrent_limit mismatch';
    END IF;
    IF job.concurrency_time_window_s IS DISTINCT FROM OLD.__concurrency_time_window_s THEN
        RAISE EXCEPTION 'concurrency_time_window_s mismatch';
    END IF;
    IF job.cache_ttl IS DISTINCT FROM OLD.__cache_ttl THEN
        RAISE EXCEPTION 'cache_ttl mismatch';
    END IF;
    IF job.timeout IS DISTINCT FROM OLD.__timeout THEN
        RAISE EXCEPTION 'timeout mismatch';
    END IF;
    IF job.priority IS DISTINCT FROM OLD.priority THEN
        RAISE EXCEPTION 'priority mismatch';
    END IF;
    IF job.args::TEXT IS DISTINCT FROM OLD.__args::TEXT AND OLD.__args->>'_ENTRYPOINT_OVERRIDE' IS DISTINCT FROM '__WM_PREPROCESSOR' THEN
        RAISE EXCEPTION 'args mismatch';
    END IF;
    IF job.pre_run_error IS DISTINCT FROM OLD.__pre_run_error THEN
        RAISE EXCEPTION 'pre_run_error mismatch';
    END IF;
    -- v2_job_runtime:
    SELECT * INTO job_runtime FROM v2_job_runtime WHERE id = OLD.id;
    IF job_runtime.ping IS DISTINCT FROM OLD.__last_ping THEN
        RAISE EXCEPTION 'ping mismatch';
    END IF;
    IF job_runtime.memory_peak IS DISTINCT FROM OLD.__mem_peak THEN
        RAISE EXCEPTION 'memory_peak mismatch';
    END IF;
    -- v2_job_status:
    IF EXISTS(SELECT 1 FROM v2_job_status  WHERE id = OLD.id) THEN
        SELECT * INTO job_status FROM v2_job_status WHERE id = OLD.id;
        IF job_status.flow_status::TEXT IS DISTINCT FROM OLD.__flow_status::TEXT THEN
            RAISE EXCEPTION 'flow_status mismatch';
        END IF;
        IF job_status.flow_leaf_jobs::TEXT IS DISTINCT FROM OLD.__leaf_jobs::TEXT THEN
            RAISE EXCEPTION 'leaf_jobs mismatch';
        END IF;
    END IF;
    RETURN OLD;
END $$ LANGUAGE PLPGSQL;

CREATE OR REPLACE TRIGGER zzz_v2_job_queue_integrity_check_before_delete
    BEFORE DELETE ON v2_job_queue
    FOR EACH ROW
EXECUTE FUNCTION zzz_v2_job_queue_integrity_check();

-- TODO(uael): remove before phase 4
CREATE OR REPLACE FUNCTION zzz_v2_job_completed_integrity_check() RETURNS TRIGGER AS $$
DECLARE job v2_job;
BEGIN
    IF (NEW.canceled_by IS NOT NULL) IS DISTINCT FROM NEW.__canceled THEN
        RAISE EXCEPTION 'canceled mismatch';
    END IF;
    SELECT * INTO job FROM v2_job WHERE id = NEW.id;
    IF job.tag IS DISTINCT FROM NEW.__tag THEN
        RAISE EXCEPTION 'tag mismatch % %', job.tag, NEW.__tag;
    END IF;
    IF job.workspace_id IS DISTINCT FROM NEW.workspace_id THEN
        RAISE EXCEPTION 'workspace_id mismatch';
    END IF;
    IF job.created_at IS DISTINCT FROM NEW.__created_at THEN
        RAISE EXCEPTION 'created_at mismatch';
    END IF;
    IF job.created_by IS DISTINCT FROM NEW.__created_by THEN
        RAISE EXCEPTION 'created_by mismatch';
    END IF;
    IF job.permissioned_as IS DISTINCT FROM NEW.__permissioned_as THEN
        RAISE EXCEPTION 'permissioned_as mismatch';
    END IF;
    IF job.permissioned_as_email IS DISTINCT FROM NEW.__email THEN
        RAISE EXCEPTION 'permissioned_as_email mismatch';
    END IF;
    IF job.kind IS DISTINCT FROM NEW.__job_kind THEN
        RAISE EXCEPTION 'kind mismatch';
    END IF;
    IF job.runnable_id IS DISTINCT FROM NEW.__script_hash THEN
        RAISE EXCEPTION 'runnable_id mismatch';
    END IF;
    IF job.runnable_path IS DISTINCT FROM NEW.__script_path THEN
        RAISE EXCEPTION 'runnable_path mismatch';
    END IF;
    IF job.parent_job IS DISTINCT FROM NEW.__parent_job THEN
        RAISE EXCEPTION 'parent_job mismatch';
    END IF;
    IF job.script_lang IS DISTINCT FROM NEW.__language THEN
        RAISE EXCEPTION 'script_lang mismatch';
    END IF;
    IF job.script_entrypoint_override IS DISTINCT FROM NULLIF(NEW.__args->>'_ENTRYPOINT_OVERRIDE', '__WM_PREPROCESSOR')
        AND NEW.__args->>'reason' IS DISTINCT FROM 'PREPROCESSOR_ARGS_ARE_DISCARDED'
    THEN
        RAISE EXCEPTION 'script_entrypoint_override mismatch';
    END IF;
    IF (job.flow_step_id IS NOT NULL) IS DISTINCT FROM NEW.__is_flow_step THEN
        RAISE EXCEPTION 'is_flow_step mismatch';
    END IF;
    IF job.trigger IS DISTINCT FROM NEW.__schedule_path THEN
        RAISE EXCEPTION 'trigger mismatch';
    END IF;
    IF job.visible_to_owner IS DISTINCT FROM NEW.__visible_to_owner THEN
        RAISE EXCEPTION 'visible_to_owner mismatch';
    END IF;
    IF job.args::TEXT IS DISTINCT FROM NEW.__args::TEXT AND NEW.__args->>'_ENTRYPOINT_OVERRIDE' IS DISTINCT FROM '__WM_PREPROCESSOR' THEN
        RAISE EXCEPTION 'args mismatch';
    END IF;
    RETURN NEW;
END $$ LANGUAGE PLPGSQL;

CREATE OR REPLACE TRIGGER zzz_v2_job_completed_integrity_check_after_insert
    AFTER INSERT ON v2_job_completed
    FOR EACH ROW
EXECUTE FUNCTION zzz_v2_job_completed_integrity_check();
