<?php
/**
 * Sentinel — Hash binding and domain/IP validation
 * 
 * Generates and verifies the bind hash that locks a license
 * to a specific domain + server IP + installation path.
 */

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

// ─── Salt fragment Part 2 (Part 1 is in cipher.php) ─────────────────
define('_SENTINEL_SALT_B', 'Yz3@nW8!fJ5dHq');

/**
 * Normalize a domain name for consistent hashing.
 * Strips www., converts to lowercase, trims whitespace.
 * 
 * @param string $domain Raw domain
 * @return string Normalized domain
 */
function _sentinel_normalize_domain($domain) {
    $d = strtolower(trim($domain));
    $d = preg_replace('/^www\./', '', $d);
    // Remove port number if present
    $d = preg_replace('/:\d+$/', '', $d);
    return $d;
}

/**
 * Generate the binding hash.
 * 
 * bind_hash = sha256(domain + server_ip + license_key + install_path + combined_salt)
 * 
 * @param string $domain Normalized domain
 * @param string $ip Server IP address
 * @param string $licenseKey The purchase/license key
 * @param string|null $installPath Override for install path (defaults to PATH constant)
 * @return string 64-char hex hash
 */
function _sentinel_generate_hash($domain, $ip, $licenseKey, $installPath = null) {
    if ($installPath === null) {
        $installPath = defined('PATH') ? PATH : dirname(__DIR__);
    }
    
    $combined = implode('||', [
        _sentinel_normalize_domain($domain),
        $ip,
        $licenseKey,
        $installPath,
        _CIPHER_SALT_A,  // from cipher.php
        _SENTINEL_SALT_B, // from sentinel.php
    ]);
    
    return hash('sha256', $combined);
}

/**
 * Verify a stored hash against current environment.
 * 
 * @param string $storedHash The hash stored in license.dat
 * @param string $domain Current domain
 * @param string $ip Current server IP
 * @param string $licenseKey The license key
 * @param string|null $installPath Override for install path
 * @return bool True if hash matches
 */
function _sentinel_verify($storedHash, $domain, $ip, $licenseKey, $installPath = null) {
    $currentHash = _sentinel_generate_hash($domain, $ip, $licenseKey, $installPath);
    return hash_equals($storedHash, $currentHash);
}

/**
 * Get the current domain from server variables.
 * 
 * @return string Normalized domain
 */
function _sentinel_current_domain() {
    $host = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? 'unknown';
    return _sentinel_normalize_domain($host);
}

/**
 * Get the current server IP.
 * 
 * @return string Server IP
 */
function _sentinel_current_ip() {
    return $_SERVER['SERVER_ADDR'] ?? '0.0.0.0';
}

/**
 * Generate an integrity checksum from multiple file contents.
 * Used by the DB integrity system.
 * 
 * @param string $licenseDatPath Path to license.dat
 * @param string $systemLockPath Path to system.lock
 * @param string $bindHash The bind hash
 * @return string 64-char hex checksum
 */
function _sentinel_integrity_checksum($licenseDatPath, $systemLockPath, $bindHash) {
    $parts = [];
    
    if (file_exists($licenseDatPath)) {
        $parts[] = md5_file($licenseDatPath);
    } else {
        $parts[] = 'MISSING';
    }
    
    if (file_exists($systemLockPath)) {
        $parts[] = md5_file($systemLockPath);
    } else {
        $parts[] = 'MISSING';
    }
    
    $parts[] = $bindHash;
    $parts[] = _CIPHER_SALT_A . _SENTINEL_SALT_B;
    
    return hash('sha256', implode('||', $parts));
}
