<?php

declare(strict_types=1);

namespace HyperfTest\Cases\Integration\System;

use Hyperf\DbConnection\Db;
use PHPUnit\Framework\TestCase;

/**
 * P22.2 物化层 schema 烟雾测试：断言迁移已应用、索引齐备、刷新策略已注册。
 *
 * @internal
 * @coversNothing
 */
class MaterializedViewSmokeTest extends TestCase
{
    /**
     * @template T
     * @param callable(): T $callback
     * @return T
     */
    protected function runInCoroutine(callable $callback): mixed
    {
        if (\Swoole\Coroutine::getCid() > 0) {
            return $callback();
        }

        $result = null;
        $exception = null;
        \Swoole\Coroutine\run(static function () use ($callback, &$result, &$exception): void {
            try {
                $result = $callback();
            } catch (\Throwable $e) {
                $exception = $e;
            }
        });
        if ($exception !== null) {
            throw $exception;
        }
        return $result;
    }

    public function test_orders_daily_by_paid_matview_exists(): void
    {
        $rows = $this->runInCoroutine(static fn () => Db::select(
            "SELECT matviewname FROM pg_matviews WHERE matviewname = 'orders_daily_by_paid'"
        ));
        $this->assertCount(1, $rows);
    }

    public function test_orders_daily_by_paid_has_six_indexes(): void
    {
        $rows = $this->runInCoroutine(static fn () => Db::select(
            "SELECT indexname FROM pg_indexes WHERE tablename = 'orders_daily_by_paid'"
        ));
        $this->assertCount(6, $rows, '应有 1 UNIQUE + 5 复合 = 6 个索引');
    }

    public function test_orders_daily_by_created_refresh_policy_registered(): void
    {
        $rows = $this->runInCoroutine(static fn () => Db::select(
            "SELECT job_id FROM timescaledb_information.jobs
             WHERE proc_name = 'policy_refresh_continuous_aggregate'
               AND hypertable_name = 'orders_daily_by_created'"
        ));
        $this->assertCount(1, $rows);
    }
}
