<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

return new class extends Migration
{
    /**
     * CREATE INDEX CONCURRENTLY cannot run inside a transaction, and `prefixes` is large enough and
     * written to often enough (prefix:sort runs on a minute timer) that a plain build holding a SHARE
     * lock is not worth the outage.
     */
    public $withinTransaction = false;

    public function up()
    {
        // OculiProcessEvents resolves an attack destination to every prefix containing it with
        // `set_masklen(address, mask) >>= <destination>`. Without an operator class that understands
        // containment this is a sequential scan of the whole table per destination; with it, it is an
        // index probe. Partial on the live rows because that is the only shape the lookup ever takes.
        DB::statement('CREATE INDEX CONCURRENTLY IF NOT EXISTS prefixes_containment_gist
                            ON prefixes USING gist ((set_masklen(address, mask)) inet_ops)
                         WHERE deleted_at IS NULL');

        // The queue is drained by id over the unprocessed rows, so keep the backlog scan proportional
        // to the backlog rather than to everything that is waiting on the fortnightly prune.
        DB::statement('CREATE INDEX CONCURRENTLY IF NOT EXISTS mitigation_event_queue_pending
                            ON mitigation_event_queue (id)
                         WHERE processed_at IS NULL');

        // Attribution reads the closure from the subnet side and the subtenancy from the prefix side.
        DB::statement('CREATE INDEX CONCURRENTLY IF NOT EXISTS prefix_subtenants_prefix_id
                            ON prefix_subtenants (prefix_id)');
    }

    public function down()
    {
        DB::statement('DROP INDEX CONCURRENTLY IF EXISTS prefixes_containment_gist');
        DB::statement('DROP INDEX CONCURRENTLY IF EXISTS mitigation_event_queue_pending');
        DB::statement('DROP INDEX CONCURRENTLY IF EXISTS prefix_subtenants_prefix_id');
    }
};
