<?php
/**
 * Shield — File integrity checks and LOCKED MODE enforcement
 * 
 * Checks that all critical license files exist and are untampered.
 * If any issue is detected, the system enters LOCKED MODE.
 */

if (!defined('BASEPATH')) { http_response_code(403); exit; }

/**
 * List of critical files that must exist for the system to function.
 * Relative to the project root (PATH constant).
 * 
 * @return array File paths relative to PATH
 */
function _shield_critical_files() {
    return [
        '/config/license.dat',
        '/config/system.lock',
        '/core/bootstrap.php',
        '/core/cipher.php',
        '/core/sentinel.php',
        '/core/shield.php',
    ];
}

/**
 * Check if all critical files exist and are non-empty.
 * 
 * @return bool True if all files pass
 */
function _shield_check_files() {
    $root = defined('PATH') ? PATH : dirname(__DIR__);
    
    foreach (_shield_critical_files() as $file) {
        $fullPath = $root . $file;
        if (!file_exists($fullPath) || !is_readable($fullPath)) {
            return false;
        }
        // Files must have content
        if (filesize($fullPath) === 0) {
            return false;
        }
    }
    
    return true;
}

/**
 * Verify the system.lock file contains a valid fingerprint.
 * The fingerprint is generated during installation.
 * 
 * @param string $lockPath Path to system.lock
 * @return array|false Lock data on success, false on failure
 */
function _shield_verify_lock($lockPath) {
    if (!file_exists($lockPath) || !is_readable($lockPath)) {
        return false;
    }
    
    $raw = @file_get_contents($lockPath);
    if ($raw === false || empty($raw)) {
        return false;
    }
    
    $data = @json_decode($raw, true);
    if (!is_array($data)) {
        return false;
    }
    
    // Must contain required fields
    $required = ['fingerprint', 'installed_at', 'php_version'];
    foreach ($required as $field) {
        if (empty($data[$field])) {
            return false;
        }
    }
    
    // Verify fingerprint matches current installation path
    $expectedFp = _shield_generate_fingerprint();
    if (!hash_equals($data['fingerprint'], $expectedFp)) {
        return false;
    }
    
    return $data;
}

/**
 * Generate installation fingerprint.
 * Based on install path + salt so it can't be forged.
 * 
 * @return string 64-char hex fingerprint
 */
function _shield_generate_fingerprint() {
    $installPath = defined('PATH') ? PATH : dirname(__DIR__);
    $salt = defined('_CIPHER_SALT_A') ? _CIPHER_SALT_A : '';
    $salt .= defined('_SENTINEL_SALT_B') ? _SENTINEL_SALT_B : '';
    return hash('sha256', 'FINGERPRINT||' . $installPath . '||' . $salt);
}

/**
 * Create the system.lock file during installation.
 * 
 * @param string $lockPath Path to write system.lock
 * @return bool Success
 */
function _shield_create_lock($lockPath) {
    $data = [
        'fingerprint'  => _shield_generate_fingerprint(),
        'installed_at' => date('Y-m-d H:i:s'),
        'php_version'  => PHP_VERSION,
        'server_os'    => PHP_OS,
        'sapi'         => php_sapi_name(),
    ];
    
    $dir = dirname($lockPath);
    if (!is_dir($dir)) {
        @mkdir($dir, 0755, true);
    }
    
    return @file_put_contents($lockPath, json_encode($data, JSON_PRETTY_PRINT), LOCK_EX) !== false;
}

/**
 * Check the DB integrity table for lock status.
 * Falls back gracefully if DB is unavailable.
 * 
 * @param PDO|null $conn Database connection
 * @return bool True if NOT locked (safe to proceed)
 */
function _shield_check_db_lock($conn) {
    if ($conn === null) {
        return true; // Can't check DB, rely on file checks
    }
    
    try {
        $stmt = $conn->prepare("SELECT locked, lock_reason FROM system_integrity WHERE id = 1 LIMIT 1");
        $stmt->execute();
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$row) {
            return false; // No integrity row = tampered
        }
        
        return (int)$row['locked'] === 0;
    } catch (Exception $e) {
        // Table might not exist yet (first install)
        // Check if table exists at all
        try {
            $check = $conn->query("SHOW TABLES LIKE 'system_integrity'");
            if ($check->rowCount() === 0) {
                return true; // Table doesn't exist yet, skip DB check
            }
            return false; // Table exists but query failed = suspicious
        } catch (Exception $e2) {
            return true; // DB completely unavailable, rely on file checks
        }
    }
}

/**
 * Enter LOCKED MODE — show generic error and halt execution.
 * Never reveals internal details.
 */
function _shield_lock() {
    // Clean any output buffers
    while (ob_get_level() > 0) {
        @ob_end_clean();
    }
    
    http_response_code(403);
    echo '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8">';
    echo '<meta name="viewport" content="width=device-width,initial-scale=1.0">';
    echo '<title>Access Denied</title>';
    echo '<style>';
    echo '*{margin:0;padding:0;box-sizing:border-box}';
    echo 'body{min-height:100vh;display:flex;align-items:center;justify-content:center;';
    echo 'font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;';
    echo 'background:#0a0a0a;color:#e0e0e0}';
    echo '.m{text-align:center;padding:60px 40px}';
    echo '.m h1{font-size:20px;color:#ff4444;margin-bottom:12px;letter-spacing:1px}';
    echo '.m p{font-size:14px;color:#666;margin-top:8px}';
    echo '</style></head><body>';
    echo '<div class="m">';
    echo '<h1>This installation is not authorized.</h1>';
    echo '<p>Contact your panel provider for support.</p>';
    echo '</div></body></html>';
    exit;
}
