<?php
/**
 * generate_integrity.php
 *
 * Run this script after every extension code change to refresh the
 * authoritative hash list (data/extension_integrity.json).
 *
 * Multi-baseline support: hashes from multiple extension folders are merged
 * (UNION). Extension only needs ONE of its files to match per relative path.
 * This lets dev (.dev/extension-localhost) and prod (TTEKNO-APPS-exstension)
 * coexist without lockdown — useful during development.
 *
 * Usage:
 *   - Auto-detect both folders (recommended):
 *       php generate_integrity.php
 *   - Single folder explicit:
 *       php generate_integrity.php /path/to/extension/folder
 *   - Web access (admin only):
 *       https://tekno-apps.texaproject.com/inject/generate_integrity.php?key=YOUR_SECRET_KEY
 */

// === Config ===
$INTEGRITY_FILE = __DIR__ . '/data/extension_integrity.json';
$SECRET_KEY     = '4rg0v14N@#480343';

$TRACKED_FILES = [
    'manifest.json',
    'background.js',
    'content.js',
    'flow_lock_content.js',
    'popup.html',
    'popup.js',
    'overlay.html',
    'rules.json',
    'security/securityConfig.js',
    'security/auditLog.js',
    'security/apiClient.js',
    'security/antiTamper.js',
    'security/licenseCheck.js',
    'security/permissionGate.js',
    'security/authGuard.js',
    'security/cookieGuard.js',
    'security/integrityGuard.js',
];

function _err($msg) {
    if (php_sapi_name() === 'cli') {
        fwrite(STDERR, $msg . "\n");
    } else {
        header('Content-Type: application/json');
        echo json_encode(['success' => false, 'error' => $msg]);
    }
    exit(1);
}

// === Resolve extension paths (multi-baseline) ===
$extPaths = [];
if (php_sapi_name() === 'cli') {
    if (isset($argv[1])) {
        // Support multiple paths separated by ";"
        $rawArg = $argv[1];
        $parts = explode(';', $rawArg);
        foreach ($parts as $p) {
            $p = trim($p);
            if ($p === '') continue;
            if (!is_dir($p)) {
                fwrite(STDERR, "Warning: not a directory: $p\n");
                continue;
            }
            $extPaths[] = realpath($p);
        }
    } else {
        // Auto-detect known folders
        $candidates = [
            realpath(__DIR__ . '/../../EXTENSION-BUILDS/02-PROD-RAW'),
            realpath(__DIR__ . '/../../EXTENSION-BUILDS/03-PROD-OBFUSCATED'),
            realpath(__DIR__ . '/../../TTEKNO-APPS-exstension'),
            realpath(__DIR__ . '/../../.dev/extension-localhost'),
        ];
        foreach ($candidates as $c) if ($c && is_dir($c)) $extPaths[] = $c;
    }
} else {
    $key = $_GET['key'] ?? '';
    if ($key !== $SECRET_KEY) {
        http_response_code(403);
        _err('Forbidden — invalid key');
    }
    $candidates = [
        realpath(__DIR__ . '/../../EXTENSION-BUILDS/02-PROD-RAW'),
        realpath(__DIR__ . '/../../EXTENSION-BUILDS/03-PROD-OBFUSCATED'),
        realpath(__DIR__ . '/../../TTEKNO-APPS-exstension'),
        realpath(__DIR__ . '/../../.dev/extension-localhost'),
    ];
    foreach ($candidates as $c) if ($c && is_dir($c)) $extPaths[] = $c;
}

if (empty($extPaths)) {
    _err('No extension folder found. Pass path as argument: php generate_integrity.php /path/to/extension');
}

// === Compute hashes — merge mode ===
// Each tracked file → array of acceptable hashes (one per source folder).
$hashes = []; // rel => array of hashes
$missing = [];
foreach ($extPaths as $extPath) {
    foreach ($TRACKED_FILES as $rel) {
        $abs = $extPath . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $rel);
        if (!file_exists($abs)) {
            $missing[] = basename($extPath) . '/' . $rel;
            continue;
        }
        $h = hash_file('sha256', $abs);
        if (!isset($hashes[$rel])) $hashes[$rel] = [];
        if (!in_array($h, $hashes[$rel], true)) {
            $hashes[$rel][] = $h;
        }
    }
}

$payload = [
    'generated_at' => date('Y-m-d H:i:s'),
    'extension_paths' => $extPaths,
    'hashes' => $hashes,
    'multi_baseline' => true,
];

// === Save ===
@mkdir(dirname($INTEGRITY_FILE), 0755, true);
$ok = file_put_contents($INTEGRITY_FILE, json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
if ($ok === false) {
    _err('Failed to write ' . $INTEGRITY_FILE);
}

// === Output ===
if (php_sapi_name() === 'cli') {
    echo "✓ Integrity file written: $INTEGRITY_FILE\n";
    echo "  Sources: " . count($extPaths) . " folder(s)\n";
    foreach ($extPaths as $p) echo "    - $p\n";
    echo "  Tracked: " . count($hashes) . " file(s)\n";
    if ($missing) echo "  Missing: " . implode(', ', array_unique($missing)) . "\n";
} else {
    header('Content-Type: application/json');
    echo json_encode([
        'success' => true,
        'sources' => count($extPaths),
        'tracked' => count($hashes),
        'missing' => array_values(array_unique($missing)),
        'file' => basename($INTEGRITY_FILE),
        'generated_at' => $payload['generated_at'],
    ], JSON_PRETTY_PRINT);
}
