CREATE SCHEMA drive;

CREATE TYPE drive.architecture_t AS ENUM (
    'all',
    'arm64'
);

CREATE TYPE drive.branch_t AS ENUM (
    'testing',
    'prestable',
    'stable'
);

CREATE TABLE drive.package (
    id bigserial PRIMARY KEY,
    name text NOT NULL,
    version text NOT NULL,
    arch drive.architecture_t NOT NULL,
    created_at timestamp NOT NULL,
    s3_key text NOT NULL,
    md5_sum text NOT NULL,
    size bigint NOT NULL,

    UNIQUE(name, version, arch)
);

CREATE TABLE drive.scope (
    id bigserial PRIMARY KEY,
    hardware text NOT NULL,
    arch drive.architecture_t NOT NULL,
    branch drive.branch_t NOT NULL,
    device_id text
);

CREATE UNIQUE INDEX scope_hw_arch_branch_device_idx
ON drive.scope (hardware, arch, branch, device_id)
WHERE device_id IS NOT NULL;

CREATE UNIQUE INDEX scope_hw_arch_branch_null_idx
ON drive.scope (hardware, arch, branch)
WHERE device_id IS NULL;

CREATE TABLE drive.experiment (
    id bigserial PRIMARY KEY,
    percent smallint NOT NULL CHECK (percent > 0 AND percent < 100),
    salt text,
    description text
);

CREATE TABLE drive.package_rollout (
    id bigserial PRIMARY KEY,
    package_name text NOT NULL,
    scope_id bigint NOT NULL REFERENCES drive.scope (id) ON DELETE CASCADE,
    package_id bigint NOT NULL REFERENCES drive.package (id) ON DELETE CASCADE,
    is_experimental bool NOT NULL DEFAULT false,
    experiment_id bigint REFERENCES drive.experiment (id) ON DELETE CASCADE,
    active_since timestamp NOT NULL,

    UNIQUE(package_name, scope_id, is_experimental)
);

CREATE TABLE drive.package_rollout_history (
    id bigserial PRIMARY KEY,
    package_name text NOT NULL,
    scope_id bigint NOT NULL REFERENCES drive.scope (id) ON DELETE CASCADE,
    package_id bigint NOT NULL REFERENCES drive.package (id) ON DELETE CASCADE,
    is_experimental bool NOT NULL,
    experiment_id bigint REFERENCES drive.experiment (id) ON DELETE CASCADE,
    active_since timestamp NOT NULL,
    active_till timestamp NOT NULL
);
