<?php

if (PHP_SAPI !== 'cli') {
    http_response_code(404);
    exit;
}

const LICENSE_RELEASE_VERSION = '1.1.6';

$root = str_replace('\\', '/', dirname(__DIR__));
$releaseDir = $root . '/release/' . LICENSE_RELEASE_VERSION;
$packageFile = $releaseDir . '/EnterpriseCMS-license-center-' . LICENSE_RELEASE_VERSION . '-upgrade.zip';
$files = array(
    '.htaccess',
    'nginx.htaccess',
    'core/lib/safe_zip.php',
    'core/lib/upgrade_public_key.pem',
    'license-center/admin.php',
    'license-center/admin_login.php',
    'license-center/api.php',
    'license-center/api/index.php',
    'license-center/api/qrcode.php',
    'license-center/check_order.php',
    'license-center/db_upgrade.php',
    'license-center/db_upgrade_20260608.php',
    'license-center/db_upgrade_support.php',
    'license-center/install.php',
    'license-center/install78979d.php',
    'license-center/functions/alipay_service.php',
    'license-center/functions/process_buy_order.php',
    'license-center/lib/help_center.php',
    'license-center/lib/security.php',
    'license-center/login.php',
    'license-center/payment.php',
    'license-center/pay_api.php',
    'license-center/pay_notify.php',
    'license-center/portal_shared.php',
    'license-center/portal_templates.php',
    'license-center/portal_updates.php',
    'license-center/register.php',
    'license-center/user.php',
    'license-center/packages/yutou_1.1.6.zip',
);
$portalFiles = array(
    'license-center/index.php',
    'license-center/portal_about.php',
    'license-center/portal_cases.php',
    'license-center/portal_contact.php',
    'license-center/portal_downloads.php',
    'license-center/portal_features.php',
    'license-center/portal_help.php',
    'license-center/portal_help_detail.php',
    'license-center/portal_news.php',
    'license-center/portal_query.php',
    'license-center/portal_solutions.php',
    'license-center/portal_template_detail.php',
    'license-center/portal_versions.php',
);
$files = array_values(array_unique(array_merge($files, $portalFiles)));
$bundledFiles = array(
    'core/yutoucmsv1.1.6.zip' => $root . '/release/1.1.6/EnterpriseCMS-1.1.6-full.zip',
);

if (!class_exists('ZipArchive')) {
    throw new RuntimeException('ZipArchive extension is required.');
}
if (!is_dir($releaseDir) && !mkdir($releaseDir, 0775, true) && !is_dir($releaseDir)) {
    throw new RuntimeException('Cannot create release directory.');
}

$hashes = array();
foreach ($files as $relative) {
    $source = $root . '/' . $relative;
    if (!is_file($source)) {
        throw new RuntimeException('Missing release file: ' . $relative);
    }
    $hashes[$relative] = hash_file('sha256', $source);
}
foreach ($bundledFiles as $relative => $source) {
    if (!is_file($source)) {
        throw new RuntimeException('Missing bundled release file: ' . $relative);
    }
    $hashes[$relative] = hash_file('sha256', $source);
}

$publicKeyHash = hash_file('sha256', $root . '/core/lib/upgrade_public_key.pem');
$buildTime = date('Y-m-d H:i:s');
$jsonFlags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT;
$manifest = array(
    'name' => 'EnterpriseCMS 授权平台 ' . LICENSE_RELEASE_VERSION . ' 升级包',
    'version' => LICENSE_RELEASE_VERSION,
    'build_time' => $buildTime,
    'package_type' => 'license-center-root-overwrite',
    'file_count' => count($files) + count($bundledFiles),
    'database_upgrade' => 'php license-center/db_upgrade.php',
    'signing_public_key_sha256' => $publicKeyHash,
    'contains_signing_private_key' => false,
    'contains_database_config' => false,
    'files' => array_merge($files, array_keys($bundledFiles)),
);
$readme = <<<TXT
EnterpriseCMS 授权平台 1.1.6 升级说明

1. 备份授权平台文件和数据库，单独备份 license-center/config.php 与签名私钥。
2. 将本压缩包解压到网站根目录并完整覆盖全部同名文件，不要只替换 db_upgrade.php 等单个文件。
3. 本包不会包含或覆盖 license-center/config.php、portal_config.php、private/、backups/ 和 templates/。
4. 通过安全通道部署与公钥匹配的签名私钥到 license-center/private/package_signing_private.pem。
5. 在命令行执行：php license-center/db_upgrade.php；也可登录授权后台后进入“数据库升级”页面执行。
6. 检查 api.php?action=check_update 返回 latest_version=1.1.6。
7. 检查 package_download 响应包含 X-Package-SHA256 与 X-Package-Signature。
8. 如启用微信支付，在后台支付配置中填写最新的微信支付平台证书。
9. 验证完成后重新加载 Nginx/Apache 配置。

签名公钥 SHA-256：{$publicKeyHash}

重要：签名私钥属于部署密钥，不在本升级包中，禁止放入公开下载目录。
TXT;

$virtualFiles = array(
    'license-center-upgrade.json' => json_encode($manifest, $jsonFlags) . "\n",
    'LICENSE-CENTER-UPGRADE-README.txt' => $readme . "\n",
);
foreach ($virtualFiles as $relative => $content) {
    $hashes[$relative] = hash('sha256', $content);
}
$virtualFiles['checksums.json'] = json_encode($hashes, $jsonFlags) . "\n";

$zip = new ZipArchive();
if ($zip->open($packageFile, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
    throw new RuntimeException('Cannot create license center upgrade ZIP.');
}
foreach ($files as $relative) {
    if (!$zip->addFile($root . '/' . $relative, $relative)) {
        throw new RuntimeException('Cannot add release file: ' . $relative);
    }
}
foreach ($bundledFiles as $relative => $source) {
    if (!$zip->addFile($source, $relative)) {
        throw new RuntimeException('Cannot add bundled release file: ' . $relative);
    }
}
foreach ($virtualFiles as $relative => $content) {
    if (!$zip->addFromString($relative, $content)) {
        throw new RuntimeException('Cannot add release metadata: ' . $relative);
    }
}
$zip->close();

$zip = new ZipArchive();
if ($zip->open($packageFile) !== true) {
    throw new RuntimeException('Cannot verify license center upgrade ZIP.');
}
$entries = array();
for ($i = 0; $i < $zip->numFiles; $i++) {
    $entry = (string) $zip->getNameIndex($i);
    if ($entry === '' || $entry[0] === '/' || strpos($entry, '\\') !== false
        || preg_match('#^[A-Za-z]:/#', $entry) || preg_match('#(?:^|/)\.\.(?:/|$)#', $entry)) {
        throw new RuntimeException('Unsafe ZIP entry: ' . $entry);
    }
    if (preg_match('#^license-center/(?:config\.php|portal_config\.php|private/|backups/|templates/)#i', $entry)
        || stripos($entry, 'package_signing_private') !== false) {
        throw new RuntimeException('Forbidden release entry: ' . $entry);
    }
    $entries[$entry] = true;
}
foreach ($hashes as $relative => $expected) {
    $content = $zip->getFromName($relative);
    if ($content === false || !hash_equals($expected, hash('sha256', $content))) {
        throw new RuntimeException('Release checksum mismatch: ' . $relative);
    }
}
$zip->close();

$packageHash = hash_file('sha256', $packageFile);
file_put_contents(
    $releaseDir . '/LICENSE-CENTER-SHA256.txt',
    $packageHash . '  ' . basename($packageFile) . "\n"
);

echo json_encode(array(
    'success' => true,
    'version' => LICENSE_RELEASE_VERSION,
    'path' => $packageFile,
    'files' => count($entries),
    'bytes' => filesize($packageFile),
    'sha256' => $packageHash,
    'signing_public_key_sha256' => $publicKeyHash,
    'private_key_included' => false,
), $jsonFlags) . PHP_EOL;
