<?php
/**
 * Local host and Vite dev-server detection for asset URL resolution.
 *
 * @package FleekDash
 */

declare(strict_types=1);

namespace FleekDash\Libs\Assets;

const VITE_DEV_SERVER_MANIFEST_FILENAME = 'vite-dev-server.json';

function domainMatchesDevelopmentHost(string $current_domain, string $dev_domain): bool
{
    if ($current_domain === $dev_domain) {
        return true;
    }

    if (function_exists('str_ends_with')) {
        return str_ends_with($current_domain, '.' . $dev_domain);
    }

    $suffix = '.' . $dev_domain;

    return substr($current_domain, -strlen($suffix)) === $suffix;
}

/**
 * Whether the HTTP host is a local development hostname (fleek.test, localhost, etc.).
 * Does not imply the Vite dev server is running — use {@see isDevelopmentEnvironment()} for that.
 *
 * @since 0.1.0
 */
function isLocalDevelopmentHost(): bool
{
    static $cached = null;

    if ($cached !== null) {
        return $cached;
    }

    $current_host = $_SERVER['HTTP_HOST'] ?? '';
    $current_domain = preg_replace('/:\d+$/', '', $current_host);
    $development_domains = array(
        'fleek.test',
        'localhost',
        '127.0.0.1',
        '::1',
    );

    foreach ($development_domains as $dev_domain) {
        if (domainMatchesDevelopmentHost((string) $current_domain, $dev_domain)) {
            return $cached = true;
        }
    }

    return $cached = false;
}

/**
 * Whether to load Vite dev-server assets (HMR). True only on a local dev host while
 * {@see VITE_DEV_SERVER_MANIFEST_FILENAME} exists (written when `pnpm dev` / Vite starts).
 * If the file is missing, built assets from manifest.json are used.
 *
 * @since 0.1.0
 */
function isDevelopmentEnvironment(): bool
{
    static $cached = null;

    if ($cached !== null) {
        return $cached;
    }

    $use_vite_dev = false;
    if (isLocalDevelopmentHost() && defined('FLEEKDASH_PLUGIN_DIR')) {
        $dev_manifest_path = wp_normalize_path(
            FLEEKDASH_PLUGIN_DIR . ASSETS_DIRECTORY_NAME . '/' . VITE_DEV_SERVER_MANIFEST_FILENAME
        );
        $use_vite_dev = is_file($dev_manifest_path) && is_readable($dev_manifest_path);
    }

    return $cached = $use_vite_dev;
}

/**
 * Parsed vite-dev-server.json payload when the manifest file exists.
 *
 * @since 2.6.0
 */
function getViteDevServerManifestData(): ?object
{
    static $cached = null;
    static $resolved = false;

    if ($resolved) {
        return $cached;
    }

    $resolved = true;
    $manifest = null;

    if (defined('FLEEKDASH_PLUGIN_DIR')) {
        $dev_manifest_path = wp_normalize_path(
            FLEEKDASH_PLUGIN_DIR . ASSETS_DIRECTORY_NAME . '/' . VITE_DEV_SERVER_MANIFEST_FILENAME
        );

        if (is_file($dev_manifest_path) && is_readable($dev_manifest_path)) {
            $decoded = wp_json_file_decode($dev_manifest_path);
            if ($decoded && !empty($decoded->origin)) {
                $manifest = $decoded;
            }
        }
    }

    $cached = $manifest;

    return $manifest;
}

/**
 * Vite dev-server public origin from manifest (e.g. https://fleek.test:5175 when port changes).
 *
 * @since 2.6.0
 */
function getViteDevServerOrigin(): ?string
{
    $manifest = getViteDevServerManifestData();
    if (!$manifest || empty($manifest->origin)) {
        return null;
    }

    return untrailingslashit((string) $manifest->origin);
}
