<?php
/**
 * Build per-site env-var injections that customise the cac / cac-fpm /
 * cac-litespeed image pool sizing.
 *
 * Knobs:
 *   - fpm_max_children_override → FPM_MAX_CHILDREN (and LSAPI_CHILDREN on
 *     litespeed). Overrides detect-memory.sh's pm.max_children calculation
 *     on cac/cac-fpm and detect-memory-litespeed.sh's LSAPI_CHILDREN on
 *     cac-litespeed.
 *   - opcache_memory_mb_override → OPCACHE_MEMORY_MB (cac-litespeed only
 *     for now; entrypoint writes a per-container php.d drop-in).
 *   - opcache_max_files_override → OPCACHE_MAX_FILES (cac-litespeed only).
 *
 * Why a helper instead of inlining: there are seven call sites that build
 * docker env-var lists for site containers — create_site, recreate_site,
 * recreate_all_containers, add_container, the bulk recreate worker in
 * scripts/run-bulk-sites.php, the cpanel-import path, and the change-type
 * path. Keeping the override logic in one place avoids the seven-way drift
 * that bit us with mysql.user grants earlier this year.
 *
 * Scope: applies only to PHP container types (base_image
 * `(cac|cac-fpm|cac-litespeed):php<n>`). For Node and static-Apache types
 * we return [], so a leftover override on a re-typed site doesn't leak an
 * irrelevant env var to the new container.
 *
 * Per-image env-var contract: cac/cac-fpm honor FPM_MAX_CHILDREN;
 * cac-litespeed prefers LSAPI_CHILDREN (its entrypoint at
 * scripts/entrypoint-litespeed.sh reads both, LSAPI_CHILDREN wins). We
 * emit both for litespeed images so a future entrypoint change can't
 * silently lose the override.
 */

if (!function_exists('whp_build_php_pool_env')) {

    /**
     * @param PDO $db          Live whp PDO (mysqlmgmt::getMySQLConnection)
     * @param int $site_id     whp.sites.id
     * @return string[]        env-var KEY=value strings to merge into the
     *                         caller's $env_vars array (possibly empty)
     */
    function whp_build_php_pool_env(PDO $db, int $site_id): array {
        if ($site_id <= 0) return [];

        try {
            $stmt = $db->prepare(
                "SELECT s.fpm_max_children_override,
                        s.opcache_memory_mb_override,
                        s.opcache_max_files_override,
                        ct.base_image
                   FROM whp.sites s
                   JOIN whp.container_types ct ON s.container_type_id = ct.id
                  WHERE s.id = ?"
            );
            $stmt->execute([$site_id]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
        } catch (Throwable $e) {
            // Pre-migration deployments may not have one or both columns. Treat as
            // "no override". The bad alternative — letting the exception bubble —
            // would break the container creation path on day 0 of the migration.
            if (str_contains($e->getMessage(), 'Unknown column')) {
                return [];
            }
            error_log("whp_build_php_pool_env: $e");
            return [];
        }

        if (!$row) return [];

        // Restrict to cac / cac-fpm / cac-litespeed PHP images. Anything
        // else (Node, static Apache) doesn't have a detect-memory.sh +
        // worker pool to influence.
        $base_image = (string)$row['base_image'];
        if (!preg_match('#/(cac|cac-fpm|cac-litespeed):php\d+#', $base_image)) {
            return [];
        }
        $is_litespeed = strpos($base_image, '/cac-litespeed:') !== false;

        $env = [];

        // --- fpm_max_children_override ---
        if ($row['fpm_max_children_override'] !== null) {
            $n = (int)$row['fpm_max_children_override'];
            if ($n < 2)  $n = 2;
            if ($n > 50) $n = 50;
            if ($is_litespeed) {
                // cac-litespeed prefers LSAPI_CHILDREN; emit both so the override
                // survives any future entrypoint refactor that drops the fallback.
                $env[] = 'LSAPI_CHILDREN='   . $n;
                $env[] = 'FPM_MAX_CHILDREN=' . $n;
            } else {
                $env[] = 'FPM_MAX_CHILDREN=' . $n;
            }
        }

        // --- opcache overrides (cac-litespeed only for now) ---
        // entrypoint-litespeed.sh reads OPCACHE_MEMORY_MB / OPCACHE_MAX_FILES
        // and writes a per-container php.d ini drop-in that overrides the
        // image-default lsphp-overrides.ini values. cac/cac-fpm don't have
        // an equivalent hook yet — if a future cac entrypoint gains it, drop
        // the $is_litespeed gate.
        if ($is_litespeed) {
            if ($row['opcache_memory_mb_override'] !== null) {
                $mb = (int)$row['opcache_memory_mb_override'];
                if ($mb < 32)  $mb = 32;
                if ($mb > 512) $mb = 512;
                $env[] = 'OPCACHE_MEMORY_MB=' . $mb;
            }
            if ($row['opcache_max_files_override'] !== null) {
                $f = (int)$row['opcache_max_files_override'];
                if ($f < 2000)   $f = 2000;
                if ($f > 32000)  $f = 32000;
                $env[] = 'OPCACHE_MAX_FILES=' . $f;
            }
        }

        return $env;
    }
}
