<?php
/**
 * License Installer Controller — Anti-Tampering System
 * 
 * Two modes:
 *   1. ACTIVATION: Validate license key → create encrypted license.dat + system.lock + DB integrity
 *   2. RESET: Validate reset token from license server → clear all license data → allow re-activation
 */
if (!defined('BASEPATH')) {
    die('Direct access to the script is not allowed');
}

// Load core components for encryption and hashing
require_once PATH . '/core/cipher.php';
require_once PATH . '/core/sentinel.php';
require_once PATH . '/core/shield.php';

$title = "License Activation";
$error = '';
$success = '';
$errorText = '';
$successText = '';
$showResetForm = false;
$resetSuccess = false;

// Default form values
$formData = [
    'license_key'  => '',
    'api_url'      => 'https://smmstore.wuaze.com/api/license/activate.php',
    'product_slug' => 'paste-product-slug-here',
];

$licenseDatPath  = PATH . '/config/license.dat';
$systemLockPath  = PATH . '/config/system.lock';
$cachePath       = PATH . '/storage/license_check_cache.json';

// Check if already installed
$alreadyInstalled = file_exists($licenseDatPath) && file_exists($systemLockPath);

// ═══════════════════════════════════════════════════════════════════
// Adaptive File Permission Detection
// ═══════════════════════════════════════════════════════════════════
function _detect_safe_permissions($filePath) {
    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        return ['file_mode' => 0644, 'dir_mode' => 0755, 'env' => 'windows',
                'detail' => 'Windows detected — chmod not applicable'];
    }
    
    $sapi = php_sapi_name();
    $phpUid = function_exists('posix_geteuid') ? posix_geteuid() : -1;
    $checkPath = file_exists($filePath) ? $filePath : dirname($filePath);
    $fileUid = @fileowner($checkPath);
    if ($fileUid === false) $fileUid = -2;
    $sameOwner = ($phpUid >= 0 && $phpUid === $fileUid);
    
    if (stripos($sapi, 'fpm') !== false || stripos($sapi, 'fcgi') !== false) $env = 'php-fpm';
    elseif (stripos($sapi, 'cgi') !== false) $env = 'cgi';
    elseif (stripos($sapi, 'litespeed') !== false) $env = 'litespeed';
    elseif (stripos($sapi, 'apache') !== false) $env = $sameOwner ? 'apache-itk' : 'mod_php';
    else $env = 'unknown';
    
    if ($sameOwner) {
        return ['file_mode' => 0600, 'dir_mode' => 0700, 'env' => $env,
                'detail' => "Same owner (UID:$phpUid) — 0600/0700"];
    } else {
        return ['file_mode' => 0644, 'dir_mode' => 0755, 'env' => $env,
                'detail' => "Different owner (PHP:$phpUid/File:$fileUid) — 0644/0755"];
    }
}

// ═══════════════════════════════════════════════════════════════════
// RESET MODE — Handle reset token
// ═══════════════════════════════════════════════════════════════════
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['reset_token'])) {
    $resetToken  = trim($_POST['reset_token']);
    $licenseKey  = trim($_POST['license_key_reset'] ?? '');
    $apiUrl      = trim($_POST['api_url'] ?? $formData['api_url']);
    
    // Build the reset endpoint URL (replace activate.php with reset.php)
    $resetUrl = str_replace('activate.php', 'reset.php', $apiUrl);
    // If URL doesn't contain activate.php, try appending reset path
    if ($resetUrl === $apiUrl) {
        $resetUrl = rtrim(dirname(dirname($apiUrl)), '/') . '/api/license/reset.php';
    }
    
    // Validate reset token with license server
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => $resetUrl,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => http_build_query([
            'license_key' => $licenseKey,
            'reset_token' => $resetToken,
        ]),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_HTTPHEADER     => ['User-Agent: SMMPanel-Reset/2.0', 'Accept: application/json'],
    ]);
    
    $response = curl_exec($ch);
    $curlError = curl_error($ch);
    curl_close($ch);
    
    if ($response === false || empty($response)) {
        $error = 1;
        $errorText = 'Could not reach the license server for reset validation.';
    } else {
        $data = @json_decode($response, true);
        
        if (is_array($data) && isset($data['status']) && $data['status'] === 'reset_ok') {
            // Delete all license files
            @unlink($licenseDatPath);
            @unlink($systemLockPath);
            @unlink($cachePath);
            
            // Clear DB integrity
            try {
                $conn->exec("DELETE FROM system_integrity WHERE id=1");
            } catch (Exception $e) {}
            
            $resetSuccess = true;
            $alreadyInstalled = false;
            $success = 1;
            $successText = 'License reset successful. You can now activate a new license.';
        } else {
            $error = 1;
            $msg = $data['message'] ?? 'Invalid or expired reset token.';
            $errorText = 'Reset failed: <strong>' . htmlspecialchars($msg) . '</strong>';
        }
    }
    
    $showResetForm = true;
}

// ═══════════════════════════════════════════════════════════════════
// ACTIVATION MODE — Validate and install license
// ═══════════════════════════════════════════════════════════════════
elseif ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['license_key'])) {
    $licenseKey  = trim($_POST['license_key']);
    $apiUrl      = trim($_POST['api_url'] ?? '');
    $productSlug = trim($_POST['product_slug'] ?? '');
    
    $formData['license_key']  = $licenseKey;
    $formData['api_url']      = $apiUrl;
    $formData['product_slug'] = $productSlug;
    
    if (empty($licenseKey)) {
        $error = 1;
        $errorText = 'License key is required.';
    } elseif (empty($apiUrl) || !filter_var($apiUrl, FILTER_VALIDATE_URL)) {
        $error = 1;
        $errorText = 'A valid API URL is required.';
    } else {
        $domain = _sentinel_current_domain();
        $ip = _sentinel_current_ip();
        
        // cURL call to selling site API
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL            => $apiUrl,
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => http_build_query([
                'license_key'  => $licenseKey,
                'domain'       => $domain,
                'server_ip'    => $ip,
                'install_path' => PATH,
                'product_slug' => $productSlug,
            ]),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CONNECTTIMEOUT => 5,
            CURLOPT_TIMEOUT        => 10,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_HTTPHEADER     => ['User-Agent: SMMPanel-Installer/2.0', 'Accept: application/json'],
        ]);
        
        $response = curl_exec($ch);
        $curlError = curl_error($ch);
        curl_close($ch);
        
        if ($response === false || empty($response)) {
            $error = 1;
            $errorText = 'Could not reach the license server. Error: ' . htmlspecialchars($curlError);
        } else {
            $data = @json_decode($response, true);
            
            if (!is_array($data) || !isset($data['status'])) {
                $error = 1;
                $errorText = 'Invalid response from license server. Please check the API URL.';
            } elseif ($data['status'] === 'valid') {
                
                // ─── Generate binding hash ──────────────────────
                $bindHash = _sentinel_generate_hash($domain, $ip, $licenseKey);
                
                // ─── Build license data ─────────────────────────
                $licenseData = [
                    'license_key'  => $licenseKey,
                    'api_url'      => $apiUrl,
                    'product_slug' => $productSlug,
                    'product_id'   => $data['product_id'] ?? '',
                    'domain'       => $domain,
                    'ip'           => $ip,
                    'bind_hash'    => $bindHash,
                    'installed_at' => date('Y-m-d H:i:s'),
                    'expires_at'   => $data['expires_at'] ?? null,
                ];
                
                // ─── Ensure config directory exists ─────────────
                $configDir = dirname($licenseDatPath);
                if (!is_dir($configDir)) {
                    @mkdir($configDir, 0755, true);
                }
                
                // ─── Write encrypted license.dat ────────────────
                if (!_cipher_write_license($licenseDatPath, $licenseData)) {
                    $error = 1;
                    $errorText = 'Failed to write license file. Check that <code>config/</code> is writable.';
                } else {
                    // ─── Create system.lock ──────────────────────
                    if (!_shield_create_lock($systemLockPath)) {
                        @unlink($licenseDatPath); // rollback
                        $error = 1;
                        $errorText = 'Failed to create system lock file.';
                    } else {
                        // ─── Set adaptive permissions ───────────
                        $permInfo = _detect_safe_permissions($licenseDatPath);
                        @chmod($licenseDatPath, $permInfo['file_mode']);
                        @chmod($systemLockPath, $permInfo['file_mode']);
                        @chmod($configDir, $permInfo['dir_mode']);
                        
                        // ─── Create initial cache ───────────────
                        $storageDir = PATH . '/storage';
                        if (!is_dir($storageDir)) @mkdir($storageDir, 0755, true);
                        $cacheData = [
                            'status'     => 'valid',
                            'timestamp'  => time(),
                            'domain'     => $domain,
                            'checked_at' => date('Y-m-d H:i:s'),
                        ];
                        @file_put_contents($cachePath, json_encode($cacheData, JSON_PRETTY_PRINT), LOCK_EX);
                        
                        // ─── Insert DB integrity row ────────────
                        $intChecksum = _sentinel_integrity_checksum($licenseDatPath, $systemLockPath, $bindHash);
                        try {
                            // Ensure table exists
                            $sqlFile = PATH . '/database/integrity_migration.sql';
                            if (file_exists($sqlFile)) {
                                $sql = file_get_contents($sqlFile);
                                $conn->exec($sql);
                            }
                            
                            // Insert or replace integrity row
                            $stmt = $conn->prepare("REPLACE INTO system_integrity (id, license_hash, integrity_checksum, last_validated_at, locked, lock_reason) VALUES (1, :hash, :checksum, :validated, 0, NULL)");
                            $stmt->execute([
                                'hash'      => $bindHash,
                                'checksum'  => $intChecksum,
                                'validated' => date('Y-m-d H:i:s'),
                            ]);
                        } catch (Exception $e) {
                            // DB integrity is a secondary layer — don't block install
                        }
                        
                        // ─── SUCCESS ────────────────────────────
                        $success = 1;
                        $alreadyInstalled = true;
                        $successText = 'License activated successfully! Panel licensed to <strong>' . htmlspecialchars($domain) . '</strong>.';
                        
                        if (!empty($data['expires_at'])) {
                            $successText .= '<br>Expires: <strong>' . htmlspecialchars($data['expires_at']) . '</strong>';
                        }
                        $successText .= '<br><small style="color:#888;">Env: ' . htmlspecialchars($permInfo['env']) 
                                     . ' | Perms: ' . decoct($permInfo['file_mode']) . '</small>';
                    }
                }
            } else {
                $error = 1;
                $statusMsg = $data['message'] ?? 'Unknown error';
                $errorText = 'License verification failed: <strong>' . htmlspecialchars($statusMsg) . '</strong>';
            }
        }
    }
}

// ═══════════════════════════════════════════════════════════════════
// Render the install template directly
// ═══════════════════════════════════════════════════════════════════
echo $twig->render('install.twig', [
    'title'        => $title,
    'error'        => $error,
    'errorText'    => $errorText,
    'success'      => $success,
    'successText'  => $successText,
    'site'         => ['url' => URL],
    'data'         => [
        'formData'         => $formData,
        'alreadyInstalled' => $alreadyInstalled,
        'showResetForm'    => $showResetForm,
        'resetSuccess'     => $resetSuccess,
    ],
]);
exit;
