<?php
/*
 * EasyStream – JW Player Branding Migration
 * Safely updates serialized JW Player config in `db_fileplayers` to remove legacy ViewShark branding.
 * Usage: php f_scripts/migrations/update_jw_branding.php
 */

define('_ISVALID', true);

// Bootstrap core to reuse DB + config
require_once __DIR__ . '/../../f_core/config.core.php';

/**
 * Unserialize safely (no objects), returning array or null
 */
function safe_unserialize($str)
{
    if (!is_string($str) || $str === '') {
        return null;
    }
    // PHP >= 7 allows allowed_classes => false
    $data = @unserialize($str, ['allowed_classes' => false]);
    if ($data === false || !is_array($data)) {
        // Try without options for older compatibility
        $data = @unserialize($str);
        if (!is_array($data)) {
            // Some environments may deliver escaped content from DB; try un-escaping
            $clean = stripslashes($str);
            $data = @unserialize($clean, ['allowed_classes' => false]);
            if ($data === false || !is_array($data)) {
                $data = @unserialize($clean);
                if (!is_array($data)) {
                    // Last resort: stripcslashes
                    $clean2 = stripcslashes($str);
                    $data = @unserialize($clean2, ['allowed_classes' => false]);
                    if ($data === false || !is_array($data)) {
                        $data = @unserialize($clean2);
                        if (!is_array($data)) {
                            return null;
                        }
                    }
                }
            }
        }
    }
    return $data;
}

/**
 * Apply branding changes to JW config array
 */
function apply_branding(array $cfg, string $siteName, string $siteUrl): array
{
    $changed = false;

    $replacements = [
        // Remove external logo file by default; admin can set later from UI
        'jw_logo_file' => '',
        // Point links to local site if available
        'jw_logo_link' => $siteUrl,
        // Update right-click text/link
        'jw_rc_text' => 'Powered by ' . ($siteName ?: 'EasyStream'),
        'jw_rc_link' => $siteUrl,
    ];

    foreach ($replacements as $key => $value) {
        if (array_key_exists($key, $cfg) && $cfg[$key] !== $value) {
            $cfg[$key] = $value;
            $changed = true;
        }
    }

    // If jw_share_enabled is set, ensure no external domains are hardcoded in share link defaults
    if (isset($cfg['jw_share_link']) && is_string($cfg['jw_share_link'])) {
        // Replace known legacy domains if present
        $legacy = ['viewsharkdemo.com', 'viewshark.com'];
        foreach ($legacy as $dom) {
            if (stripos($cfg['jw_share_link'], $dom) !== false) {
                $cfg['jw_share_link'] = '';
                $changed = true;
                break;
            }
        }
    }

    $cfg['__changed__'] = $changed; // marker for caller
    return $cfg;
}

try {
    global $db, $cfg; // from config.core.php

    if (!isset($db)) {
        throw new Exception('Database connection not initialized.');
    }

    $siteName = $cfg['site_name'] ?? 'EasyStream';
    $siteUrl  = $cfg['site_url'] ?? '';

    $targets = ['jw_local', 'jw_embed'];
    $updated = 0;

    foreach ($targets as $name) {
        $rs = $db->Execute("SELECT `db_id`, `db_config` FROM `db_fileplayers` WHERE `db_name` = ? LIMIT 1", [$name]);
        if ($rs && !$rs->EOF) {
            $dbId = (int)$rs->fields['db_id'];
            $raw  = $rs->fields['db_config'];
            $arr  = safe_unserialize($raw);

            if (is_array($arr)) {
                $arr = apply_branding($arr, $siteName, $siteUrl);
                $changed = !empty($arr['__changed__']);
                unset($arr['__changed__']);

                if ($changed) {
                    $serialized = serialize($arr);
                    $ok = $db->Execute("UPDATE `db_fileplayers` SET `db_config` = ? WHERE `db_id` = ?", [$serialized, $dbId]);
                    if ($ok) {
                        echo "Updated branding for {$name} (db_id={$dbId})\n";
                        $updated++;
                    } else {
                        echo "Failed to update {$name} (db_id={$dbId}): " . $db->ErrorMsg() . "\n";
                    }
                } else {
                    echo "No changes needed for {$name}\n";
                }
            } else {
                // Fallback: attempt in-place serialized string rewriting for known keys
                $orig = (string)$raw;
                $updatedSerialized = $orig;

                $kv = [
                    'jw_logo_file' => '',
                    'jw_logo_link' => $siteUrl,
                    'jw_rc_text'   => 'Powered by ' . ($siteName ?: 'EasyStream'),
                    'jw_rc_link'   => $siteUrl,
                ];

                $didChange = false;
                foreach ($kv as $k => $v) {
                    $escapedKey = preg_quote($k, '/');
                    $replacement = function ($m) use ($v) {
                        $len = strlen($v);
                        $safe = str_replace('"', '"', $v); // value is plain; ensure quotes are safe
                        return $m[1] . 's:' . $len . ':"' . $safe . '";';
                    };
                    $pattern = '/(s:\d+:"' . $escapedKey . '";s:)\d+:("[\s\S]*?");/';
                    $new = preg_replace_callback($pattern, $replacement, $updatedSerialized, 1, $count);
                    if ($count > 0 && is_string($new)) {
                        $updatedSerialized = $new;
                        $didChange = true;
                    }
                }

                if ($didChange) {
                    $ok = $db->Execute("UPDATE `db_fileplayers` SET `db_config` = ? WHERE `db_id` = ?", [$updatedSerialized, $dbId]);
                    if ($ok) {
                        echo "Updated branding (fallback) for {$name} (db_id={$dbId})\n";
                        $updated++;
                    } else {
                        echo "Failed fallback update {$name} (db_id={$dbId}): " . $db->ErrorMsg() . "\n";
                    }
                } else {
                    $snippet = substr((string)$raw, 0, 160);
                    echo "Could not unserialize config for {$name}; snippet: " . str_replace(["\n","\r"], ['\\n',''], $snippet) . "\n";
                }
            }
        } else {
            echo "No db_fileplayers row found for {$name}; skipping.\n";
        }
    }

    echo "Done. Updated {$updated} row(s).\n";
    exit(0);
} catch (Throwable $e) {
    // Best-effort logging
    if (class_exists('VLogger')) {
        $logger = VLogger::getInstance();
        $logger->log(VLogger::ERROR, 'JW branding migration failed', ['error' => $e->getMessage()]);
    }
    fwrite(STDERR, 'Error: ' . $e->getMessage() . "\n");
    exit(1);
}
