create extension if not exists postgis;

drop table if exists eventhub.event_detail;
drop table if exists eventhub.acquired_event;
drop table if exists eventhub.event;

create table eventhub.event (
    id uuid not null,
    event_source_id integer not null references eventhub.event_source(id),
    data_package_id uuid not null references eventhub.data_package(id),

    external_source_event_id text not null,

    driver_entity_id uuid references eventhub.source_master_entity(id),
    vehicle_entity_id uuid references eventhub.source_master_entity(id),
    source_package_entity_id uuid references eventhub.source_master_entity(id),

    occurred_at timestamptz not null,
    received_partner_at timestamptz,
    received_hub_at timestamptz not null default now(),

    event_domain text not null,
    event_type text not null,
    lifecycle text not null,

    odometer_m bigint,
    position geography(Point, 4326),

    payload jsonb not null default '{}'::jsonb,
    manual_entry boolean not null default false,

    source_record_key_hash text not null,
    event_signature_hash text,

    created_at timestamptz not null default now(),

    constraint pk_event primary key (occurred_at, id),
    constraint chk_event_driver_or_vehicle_ref check (
        driver_entity_id is not null
        or vehicle_entity_id is not null
    )
);

create unique index ux_event_source_record
    on eventhub.event(source_record_key_hash);

create index idx_event_signature
    on eventhub.event(event_signature_hash)
    where event_signature_hash is not null;

create index idx_event_source_time
    on eventhub.event(event_source_id, occurred_at desc);

create index idx_event_package_time
    on eventhub.event(data_package_id, occurred_at desc);

create index idx_event_domain_type_time
    on eventhub.event(event_domain, event_type, occurred_at desc);

create index idx_event_driver_time
    on eventhub.event(driver_entity_id, occurred_at desc)
    where driver_entity_id is not null;

create index idx_event_vehicle_time
    on eventhub.event(vehicle_entity_id, occurred_at desc)
    where vehicle_entity_id is not null;

create index idx_event_position_gist
    on eventhub.event using gist(position)
    where position is not null;

create index idx_event_payload_gin
    on eventhub.event using gin(payload);

create table eventhub.event_detail (
    event_occurred_at timestamptz not null,
    event_id uuid not null,
    detail_type text not null,
    attributes jsonb not null default '{}'::jsonb,
    created_at timestamptz not null default now(),
    constraint pk_event_detail primary key (event_occurred_at, event_id, detail_type),
    constraint fk_event_detail_event foreign key (event_occurred_at, event_id)
        references eventhub.event(occurred_at, id)
        on delete cascade
);

create index idx_event_detail_type
    on eventhub.event_detail(detail_type);

create index idx_event_detail_attributes_gin
    on eventhub.event_detail using gin(attributes);
