#!/usr/bin/env php
<?php

use support\Db;

require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../support/bootstrap.php';
require __DIR__ . '/../vendor/webman/database/src/support/Db.php';

$statements = [
    <<<SQL
CREATE TABLE IF NOT EXISTS archives (
    id BIGSERIAL PRIMARY KEY,
    archive_uid VARCHAR(26) NOT NULL UNIQUE,
    title TEXT,
    summary TEXT,
    year INTEGER,
    author TEXT,
    source TEXT,
    series TEXT,
    tags JSONB NOT NULL DEFAULT '[]'::jsonb,
    metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
    chunks JSONB NOT NULL DEFAULT '[]'::jsonb,
    created_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
)
SQL,
    'ALTER TABLE archives ADD COLUMN IF NOT EXISTS summary TEXT',
    'ALTER TABLE archives DROP COLUMN IF EXISTS content',
    'ALTER TABLE archives DROP COLUMN IF EXISTS raw',
    <<<SQL
CREATE TABLE IF NOT EXISTS chunks (
    id BIGSERIAL PRIMARY KEY,
    chunk_uid VARCHAR(64) NOT NULL UNIQUE,
    archive_uid VARCHAR(26) NOT NULL,
    chunk_index INTEGER NOT NULL,
    page_start INTEGER,
    page_end INTEGER,
    text TEXT,
    length INTEGER,
    embedding_status INTEGER NOT NULL DEFAULT 0,
    embedding_ref JSONB,
    embedding_model TEXT,
    created_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT chunks_archive_uid_foreign
        FOREIGN KEY (archive_uid)
        REFERENCES archives (archive_uid)
        ON DELETE CASCADE,
    CONSTRAINT chunks_archive_index_unique
        UNIQUE (archive_uid, chunk_index)
)
SQL,
    'CREATE INDEX IF NOT EXISTS archives_year_index ON archives (year)',
    'CREATE INDEX IF NOT EXISTS archives_series_index ON archives (series)',
    'CREATE INDEX IF NOT EXISTS archives_tags_gin_index ON archives USING GIN (tags)',
    'CREATE INDEX IF NOT EXISTS archives_metadata_gin_index ON archives USING GIN (metadata)',
    'ALTER TABLE chunks ADD COLUMN IF NOT EXISTS embedding_error TEXT',
    'ALTER TABLE chunks ADD COLUMN IF NOT EXISTS embedding_updated_at TIMESTAMPTZ',
    'ALTER TABLE chunks ADD COLUMN IF NOT EXISTS search_index_status INTEGER NOT NULL DEFAULT 0',
    'ALTER TABLE chunks ADD COLUMN IF NOT EXISTS search_index_error TEXT',
    'ALTER TABLE chunks ADD COLUMN IF NOT EXISTS search_index_updated_at TIMESTAMPTZ',
    'ALTER TABLE chunks ADD COLUMN IF NOT EXISTS created_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP',
    'ALTER TABLE chunks ADD COLUMN IF NOT EXISTS updated_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP',
    'CREATE INDEX IF NOT EXISTS chunks_archive_uid_index ON chunks (archive_uid)',
    'CREATE INDEX IF NOT EXISTS chunks_page_range_index ON chunks (archive_uid, page_start, page_end)',
    'CREATE INDEX IF NOT EXISTS chunks_embedding_status_index ON chunks (embedding_status)',
    'CREATE INDEX IF NOT EXISTS chunks_search_index_status_index ON chunks (search_index_status)',
    <<<SQL
CREATE OR REPLACE FUNCTION set_updated_time()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_time = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql
SQL,
    'DROP TRIGGER IF EXISTS archives_set_updated_time ON archives',
    'DROP TRIGGER IF EXISTS chunks_set_updated_time ON chunks',
    <<<SQL
CREATE TRIGGER archives_set_updated_time
BEFORE UPDATE ON archives
FOR EACH ROW
EXECUTE FUNCTION set_updated_time()
SQL,
    <<<SQL
CREATE TRIGGER chunks_set_updated_time
BEFORE UPDATE ON chunks
FOR EACH ROW
EXECUTE FUNCTION set_updated_time()
SQL,
];

try {
    Db::connection()->getPdo();
    echo 'Database connection ok: ' . config('database.default') . PHP_EOL;

    foreach ($statements as $statement) {
        Db::statement($statement);
    }

    echo 'Tables initialized: archives, chunks' . PHP_EOL;
} catch (Throwable $exception) {
    fwrite(STDERR, $exception::class . ': ' . $exception->getMessage() . PHP_EOL);
    exit(1);
}
