-- migrate:up

CREATE TABLE events.raw (
    event_id        bigserial,
    received_at     timestamptz NOT NULL DEFAULT now(),
    source          text NOT NULL CHECK (source IN (
                        'tracksolid_push',
                        'tracksolid_poll_list',
                        'tracksolid_poll_get',
                        'whatsapp_fuel',
                        'hr_extract',
                        'ops_action',
                        'legacy_import'
                    )),
    account_id      text,
    imei            text,
    msg_type        text,
    payload         jsonb NOT NULL,
    parser_version  int,
    parsed_at       timestamptz,
    PRIMARY KEY (event_id, received_at)
);

SELECT create_hypertable('events.raw', 'received_at', chunk_time_interval => INTERVAL '1 day');

CREATE INDEX events_raw_unparsed_idx
    ON events.raw (received_at)
    WHERE parsed_at IS NULL;

CREATE INDEX events_raw_account_imei_idx
    ON events.raw (account_id, imei, received_at DESC);

CREATE TABLE events.parsed (
    parsed_id       bigserial,
    raw_event_id    bigint NOT NULL,
    raw_received_at timestamptz NOT NULL,
    occurred_at     timestamptz NOT NULL,
    kind            text NOT NULL,
    account_id      text NOT NULL,
    imei            text NOT NULL,
    payload         jsonb NOT NULL,
    parser_version  int NOT NULL,
    inserted_at     timestamptz NOT NULL DEFAULT now(),
    PRIMARY KEY (parsed_id, occurred_at)
);

SELECT create_hypertable('events.parsed', 'occurred_at', chunk_time_interval => INTERVAL '1 day');

CREATE INDEX events_parsed_kind_imei_idx
    ON events.parsed (kind, imei, occurred_at DESC);

CREATE TABLE events.parser_errors (
    error_id        bigserial PRIMARY KEY,
    raw_event_id    bigint NOT NULL,
    raw_received_at timestamptz NOT NULL,
    parser_version  int NOT NULL,
    error_class     text NOT NULL,
    error_message   text NOT NULL,
    payload         jsonb NOT NULL,
    inserted_at     timestamptz NOT NULL DEFAULT now()
);

CREATE OR REPLACE FUNCTION events.notify_raw_new() RETURNS trigger AS $$
BEGIN
    PERFORM pg_notify('events_raw_new', NEW.event_id::text);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER events_raw_new_trigger
    AFTER INSERT ON events.raw
    FOR EACH ROW EXECUTE FUNCTION events.notify_raw_new();

CREATE OR REPLACE FUNCTION events.notify_parsed_new() RETURNS trigger AS $$
BEGIN
    PERFORM pg_notify('events_parsed_new', NEW.parsed_id::text);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER events_parsed_new_trigger
    AFTER INSERT ON events.parsed
    FOR EACH ROW EXECUTE FUNCTION events.notify_parsed_new();

-- migrate:down

DROP TRIGGER IF EXISTS events_parsed_new_trigger ON events.parsed;
DROP TRIGGER IF EXISTS events_raw_new_trigger ON events.raw;
DROP FUNCTION IF EXISTS events.notify_parsed_new();
DROP FUNCTION IF EXISTS events.notify_raw_new();
DROP TABLE IF EXISTS events.parser_errors;
DROP TABLE IF EXISTS events.parsed;
DROP TABLE IF EXISTS events.raw;
