-- Test schema for H2 in-memory database (PostgreSQL compatibility mode)
-- Excludes AI module tables (embedding_chunk, chat_session, chat_message)
-- Those tables use pgvector type which H2 doesn't support

CREATE TABLE IF NOT EXISTS event_publication
(
    id                     UUID      NOT NULL,
    listener_id            TEXT      NOT NULL,
    event_type             TEXT      NOT NULL,
    serialized_event       TEXT      NOT NULL,
    publication_date       TIMESTAMP NOT NULL,
    completion_date        TIMESTAMP,
    status                 TEXT,
    completion_attempts    INT,
    last_resubmission_date TIMESTAMP,
    PRIMARY KEY (id)
);
CREATE INDEX IF NOT EXISTS event_publication_serialized_event_hash_idx ON event_publication (serialized_event);
CREATE INDEX IF NOT EXISTS event_publication_by_completion_date_idx ON event_publication (completion_date);

CREATE TABLE IF NOT EXISTS workspaces
(
    id          UUID PRIMARY KEY,
    name        VARCHAR(150) NOT NULL,
    description VARCHAR(500),
    created_at  TIMESTAMP    NOT NULL,
    updated_at  TIMESTAMP    NOT NULL
);

CREATE TABLE IF NOT EXISTS projects
(
    id           UUID PRIMARY KEY,
    workspace_id UUID         NOT NULL REFERENCES workspaces (id) ON DELETE CASCADE,
    name         VARCHAR(150) NOT NULL,
    description  VARCHAR(500),
    created_at   TIMESTAMP    NOT NULL,
    updated_at   TIMESTAMP    NOT NULL
);

CREATE TABLE IF NOT EXISTS binaries
(
    id                   UUID PRIMARY KEY,
    project_id           UUID         NOT NULL REFERENCES projects (id) ON DELETE CASCADE,
    filename             VARCHAR(255) NOT NULL,
    file_size            BIGINT       NOT NULL,
    format               VARCHAR(30),
    architecture         VARCHAR(30),
    compiler             VARCHAR(100),
    file_path            VARCHAR(500) NOT NULL,
    static_analysis_done BOOLEAN      NOT NULL DEFAULT FALSE,
    created_at           TIMESTAMP    NOT NULL,
    updated_at           TIMESTAMP    NOT NULL
);

CREATE TABLE IF NOT EXISTS binary_dependencies
(
    id         UUID PRIMARY KEY,
    binary_id  UUID         NOT NULL REFERENCES binaries (id) ON DELETE CASCADE,
    filename   VARCHAR(255) NOT NULL,
    file_size  BIGINT       NOT NULL,
    file_path  VARCHAR(500) NOT NULL,
    created_at TIMESTAMP    NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_binary_dependencies_binary_id ON binary_dependencies (binary_id);

CREATE TABLE IF NOT EXISTS jobs
(
    id            UUID PRIMARY KEY,
    type          VARCHAR(50) NOT NULL,
    status        VARCHAR(50) NOT NULL,
    project_id    UUID        NOT NULL REFERENCES projects (id) ON DELETE CASCADE,
    binary_id     UUID        NOT NULL REFERENCES binaries (id) ON DELETE CASCADE,
    payload       JSON,
    result        JSON,
    error_message TEXT,
    retry_count   INTEGER     NOT NULL DEFAULT 0,
    created_at    TIMESTAMP   NOT NULL,
    updated_at    TIMESTAMP   NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_jobs_project_id ON jobs (project_id);
CREATE INDEX IF NOT EXISTS idx_jobs_status ON jobs (status);
CREATE INDEX IF NOT EXISTS idx_jobs_type ON jobs (type);

CREATE TABLE IF NOT EXISTS static_analysis
(
    id             UUID PRIMARY KEY,
    binary_id      UUID        NOT NULL REFERENCES binaries (id) ON DELETE CASCADE,
    job_id         UUID        REFERENCES jobs (id) ON DELETE SET NULL,
    engine         VARCHAR(20) NOT NULL,
    status         VARCHAR(50) NOT NULL,
    function_count INTEGER     NOT NULL DEFAULT 0,
    entry_point    VARCHAR(100),
    created_at     TIMESTAMP   NOT NULL,
    updated_at     TIMESTAMP   NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_static_analysis_binary_id ON static_analysis (binary_id);

CREATE TABLE IF NOT EXISTS static_function
(
    id              UUID PRIMARY KEY,
    analysis_id     UUID         NOT NULL REFERENCES static_analysis (id) ON DELETE CASCADE,
    name            VARCHAR(500) NOT NULL,
    address         VARCHAR(20)  NOT NULL,
    flags           VARCHAR(100),
    function_size   INTEGER,
    assembly        TEXT,
    decompiled_code TEXT,
    signature       VARCHAR(1000),
    created_at      TIMESTAMP    NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_static_function_analysis_id ON static_function (analysis_id);
CREATE INDEX IF NOT EXISTS idx_static_function_name ON static_function (name);

CREATE TABLE IF NOT EXISTS static_xref
(
    id        UUID PRIMARY KEY,
    caller_id UUID        NOT NULL REFERENCES static_function (id) ON DELETE CASCADE,
    callee_id UUID        NOT NULL REFERENCES static_function (id) ON DELETE CASCADE,
    type      VARCHAR(20) NOT NULL DEFAULT 'CALL',
    address   VARCHAR(20)
);
CREATE INDEX IF NOT EXISTS idx_static_xref_caller_id ON static_xref (caller_id);
CREATE INDEX IF NOT EXISTS idx_static_xref_callee_id ON static_xref (callee_id);

CREATE TABLE IF NOT EXISTS static_label
(
    id          UUID PRIMARY KEY,
    function_id UUID         NOT NULL REFERENCES static_function (id) ON DELETE CASCADE,
    name        VARCHAR(500) NOT NULL,
    address     VARCHAR(20)  NOT NULL,
    type        VARCHAR(10)  NOT NULL DEFAULT 'CALL'
);
CREATE INDEX IF NOT EXISTS idx_static_label_function_id ON static_label (function_id);

CREATE TABLE IF NOT EXISTS static_segment
(
    id            UUID PRIMARY KEY,
    analysis_id   UUID         NOT NULL REFERENCES static_analysis (id) ON DELETE CASCADE,
    name          VARCHAR(100) NOT NULL,
    start_address VARCHAR(20)  NOT NULL,
    end_address   VARCHAR(20)  NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_static_segment_analysis_id ON static_segment (analysis_id);
