SET search_path = diffalert, public;

DO $$ BEGIN
    ALTER TABLE message_attributes
        ADD COLUMN category_id text NOT NULL DEFAULT '';
    ALTER TABLE message_attributes
        ALTER COLUMN category_id DROP DEFAULT;
EXCEPTION WHEN duplicate_column THEN
    -- already added
END $$;

CREATE OR REPLACE FUNCTION insert_message_attributes(
    p_category_id text,
    p_description text)
RETURNS integer AS
$$
DECLARE
    r_attributes_id integer;
BEGIN
    LOOP
        SELECT attributes_id INTO r_attributes_id
            FROM diffalert.message_attributes
            WHERE category_id = p_category_id
                AND description = p_description;
        IF FOUND THEN
            RETURN r_attributes_id;
        END IF;

        BEGIN
            INSERT INTO diffalert.message_attributes
                    (category_id, description)
                VALUES (p_category_id, p_description)
                RETURNING attributes_id INTO r_attributes_id;
            RETURN r_attributes_id;
        EXCEPTION WHEN unique_violation THEN
            -- try SELECT again
        END;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

DO $$ BEGIN
    CREATE UNIQUE INDEX message_attributes_unique_index
        ON message_attributes (category_id, description);
EXCEPTION WHEN duplicate_table THEN
    -- already created
END $$;

DO $$ BEGIN
    CREATE INDEX messages_filtered_order_index
        ON messages (task_id, attributes_id, pri_major, pri_minor, id);
EXCEPTION WHEN duplicate_table THEN
    -- already created
END $$;


CREATE TABLE IF NOT EXISTS task_message_stats (
    task_id bigint NOT NULL,
    pri_major integer NOT NULL,
    attributes_id integer NOT NULL,
    count integer NOT NULL CHECK (count >= 0),
    PRIMARY KEY (task_id, pri_major, attributes_id)
);


DO $$ BEGIN
    CREATE INDEX task_message_stats_attrs_index
        ON task_message_stats (task_id, attributes_id);
EXCEPTION WHEN duplicate_table THEN
    -- already created
END $$;

CREATE OR REPLACE FUNCTION update_task_message_stats(
    p_task_id bigint,
    p_pri_major integer,
    p_attributes_id integer,
    p_count integer)
RETURNS integer AS
$$
DECLARE
    r_count integer;
BEGIN
    LOOP
        UPDATE diffalert.task_message_stats SET count = count + p_count
            WHERE task_id = p_task_id
                AND pri_major = p_pri_major
                AND attributes_id = p_attributes_id
            RETURNING count INTO r_count;
        IF FOUND THEN
            RETURN r_count;
        END IF;

        BEGIN
            INSERT INTO diffalert.task_message_stats
                    (task_id, pri_major, attributes_id, count)
                VALUES (p_task_id, p_pri_major, p_attributes_id, p_count);
            RETURN p_count;
        EXCEPTION
            WHEN unique_violation THEN
                -- retry update
        END;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

SET search_path = public;
