<?php
/**
 * Advanced Anti-Bot System
 * Protects against VPS, Hosting, Proxies, and Bots
 * Only allows real devices with real IPs
 */

class AdvancedAntiBot {
    private $blacklistFile = 'antibot/blacklist.txt';
    private $whitelistFile = 'antibot/whitelist.txt';
    private $logFile = 'antibot/antibot.log';
    private $configFile = 'antibot/config.json';
    
    private $config;
    private $visitorIP;
    private $userAgent;
    private $fingerprint;
    
    public function __construct() {
        $this->loadConfig();
        $this->visitorIP = $this->getRealIP();
        $this->userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        $this->fingerprint = $this->generateFingerprint();
        
        // Create necessary files if they don't exist
        $this->initializeFiles();
    }
    
    private function loadConfig() {
        $defaultConfig = [
            'enable_antibot' => true,
            'enable_blacklist' => true,
            'enable_whitelist' => true,
            'enable_vps_detection' => true,
            'enable_proxy_detection' => true,
            'enable_hosting_detection' => true,
            'enable_bot_detection' => true,
            'enable_fingerprint_check' => true,
            'max_requests_per_minute' => 10,
            'block_duration_hours' => 24,
            'allowed_countries' => ['US', 'CA', 'GB', 'AU', 'DE', 'FR', 'IT', 'ES', 'NL', 'SE'],
            'blocked_asn_keywords' => [
                'hosting', 'server', 'datacenter', 'cloud', 'vps', 'dedicated',
                'colocation', 'colo', 'amazon', 'google', 'microsoft', 'digital ocean',
                'linode', 'vultr', 'ovh', 'hetzner'
            ]
        ];
        
        if (file_exists($this->configFile)) {
            $config = json_decode(file_get_contents($this->configFile), true);
            $this->config = array_merge($defaultConfig, $config);
        } else {
            $this->config = $defaultConfig;
            $this->saveConfig();
        }
    }
    
    private function saveConfig() {
        file_put_contents($this->configFile, json_encode($this->config, JSON_PRETTY_PRINT));
    }
    
    private function initializeFiles() {
        $files = [$this->blacklistFile, $this->whitelistFile, $this->logFile];
        foreach ($files as $file) {
            if (!file_exists($file)) {
                $dir = dirname($file);
                if (!is_dir($dir)) {
                    mkdir($dir, 0755, true);
                }
                touch($file);
            }
        }
    }
    
    private function getRealIP() {
        $ipKeys = [
            'HTTP_CF_CONNECTING_IP',     // Cloudflare
            'HTTP_CLIENT_IP',
            'HTTP_X_FORWARDED_FOR',
            'HTTP_X_FORWARDED',
            'HTTP_X_CLUSTER_CLIENT_IP',
            'HTTP_FORWARDED_FOR',
            'HTTP_FORWARDED',
            'REMOTE_ADDR'
        ];
        
        foreach ($ipKeys as $key) {
            if (array_key_exists($key, $_SERVER) === true) {
                $ip = $_SERVER[$key];
                if (strpos($ip, ',') !== false) {
                    $ip = explode(',', $ip)[0];
                }
                $ip = trim($ip);
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                    return $ip;
                }
            }
        }
        
        return $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
    }
    
    private function generateFingerprint() {
        $data = [
            'ip' => $this->visitorIP,
            'user_agent' => $this->userAgent,
            'accept_language' => $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '',
            'accept_encoding' => $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '',
            'accept' => $_SERVER['HTTP_ACCEPT'] ?? '',
            'connection' => $_SERVER['HTTP_CONNECTION'] ?? '',
            'host' => $_SERVER['HTTP_HOST'] ?? '',
            'referer' => $_SERVER['HTTP_REFERER'] ?? '',
            'request_method' => $_SERVER['REQUEST_METHOD'] ?? '',
            'server_protocol' => $_SERVER['SERVER_PROTOCOL'] ?? ''
        ];
        
        return hash('sha256', serialize($data));
    }
    
    public function checkAccess() {
        if (!$this->config['enable_antibot']) {
            return true;
        }
        
        $this->logAccess('ACCESS_ATTEMPT');
        
        // Check whitelist first
        if ($this->config['enable_whitelist'] && $this->isWhitelisted()) {
            $this->logAccess('WHITELIST_ALLOWED');
            return true;
        }
        
        // Check blacklist
        if ($this->config['enable_blacklist'] && $this->isBlacklisted()) {
            $this->logAccess('BLACKLIST_BLOCKED');
            $this->blockAccess('Your IP is blacklisted');
        }
        
        // Rate limiting
        if (!$this->checkRateLimit()) {
            $this->addToBlacklist('Rate limit exceeded');
            $this->blockAccess('Too many requests');
        }
        
        // Bot detection
        if ($this->config['enable_bot_detection'] && $this->isBotUserAgent()) {
            $this->addToBlacklist('Bot user agent detected');
            $this->blockAccess('Bot detected');
        }
        
        // VPS/Hosting detection
        if ($this->config['enable_vps_detection'] && $this->isVPSOrHosting()) {
            $this->addToBlacklist('VPS/Hosting provider detected');
            $this->blockAccess('VPS/Hosting not allowed');
        }
        
        // Proxy detection
        if ($this->config['enable_proxy_detection'] && $this->isProxy()) {
            $this->addToBlacklist('Proxy detected');
            $this->blockAccess('Proxy not allowed');
        }
        
        // Fingerprint check
        if ($this->config['enable_fingerprint_check'] && !$this->isValidFingerprint()) {
            $this->addToBlacklist('Invalid fingerprint');
            $this->blockAccess('Invalid device fingerprint');
        }
        
        // Country check
        if (!$this->isAllowedCountry()) {
            $this->addToBlacklist('Country not allowed');
            $this->blockAccess('Country not allowed');
        }
        
        $this->logAccess('ACCESS_GRANTED');
        return true;
    }
    
    private function isWhitelisted() {
        $whitelist = $this->getListContent($this->whitelistFile);
        return in_array($this->visitorIP, $whitelist) || 
               in_array($this->fingerprint, $whitelist);
    }
    
    private function isBlacklisted() {
        $blacklist = $this->getListContent($this->blacklistFile);
        return in_array($this->visitorIP, $blacklist) || 
               in_array($this->fingerprint, $blacklist);
    }
    
    private function getListContent($file) {
        if (!file_exists($file)) {
            return [];
        }
        
        $content = file_get_contents($file);
        $lines = explode("\n", $content);
        $result = [];
        
        foreach ($lines as $line) {
            $line = trim($line);
            if (!empty($line) && !str_starts_with($line, '#')) {
                $result[] = $line;
            }
        }
        
        return $result;
    }
    
    private function addToBlacklist($reason) {
        $entry = $this->visitorIP . ' # ' . $reason . ' - ' . date('Y-m-d H:i:s') . "\n";
        file_put_contents($this->blacklistFile, $entry, FILE_APPEND | LOCK_EX);
        
        $fingerprintEntry = $this->fingerprint . ' # Fingerprint - ' . $reason . ' - ' . date('Y-m-d H:i:s') . "\n";
        file_put_contents($this->blacklistFile, $fingerprintEntry, FILE_APPEND | LOCK_EX);
    }
    
    private function checkRateLimit() {
        $cacheFile = 'antibot/rate_' . hash('md5', $this->visitorIP) . '.tmp';
        $now = time();
        $requests = [];
        
        if (file_exists($cacheFile)) {
            $data = json_decode(file_get_contents($cacheFile), true);
            $requests = $data['requests'] ?? [];
        }
        
        // Remove old requests (older than 1 minute)
        $requests = array_filter($requests, function($timestamp) use ($now) {
            return ($now - $timestamp) < 60;
        });
        
        // Add current request
        $requests[] = $now;
        
        // Save updated requests
        file_put_contents($cacheFile, json_encode(['requests' => $requests]));
        
        return count($requests) <= $this->config['max_requests_per_minute'];
    }
    
    private function isBotUserAgent() {
        $botPatterns = [
            'bot', 'crawler', 'spider', 'scraper', 'parser', 'checker',
            'curl', 'wget', 'python', 'java', 'perl', 'ruby', 'go-http',
            'postman', 'insomnia', 'httpie', 'rest-client', 'api-client',
            'headless', 'phantom', 'selenium', 'webdriver', 'puppeteer',
            'scrapy', 'beautifulsoup', 'mechanize', 'requests', 'urllib',
            'googlebot', 'bingbot', 'slurp', 'duckduckbot', 'baiduspider',
            'yandexbot', 'facebookexternalhit', 'twitterbot', 'linkedinbot',
            'whatsapp', 'telegram', 'discord', 'slack', 'zoom', 'skype'
        ];
        
        $userAgent = strtolower($this->userAgent);
        
        foreach ($botPatterns as $pattern) {
            if (strpos($userAgent, $pattern) !== false) {
                return true;
            }
        }
        
        // Check for missing or suspicious user agent
        if (empty($this->userAgent) || strlen($this->userAgent) < 10) {
            return true;
        }
        
        return false;
    }
    
    private function isVPSOrHosting() {
        // Get IP info from multiple sources
        $ipInfo = $this->getIPInfo();
        
        if (!$ipInfo) {
            return false;
        }
        
        $org = strtolower($ipInfo['org'] ?? '');
        $isp = strtolower($ipInfo['isp'] ?? '');
        $asName = strtolower($ipInfo['as'] ?? '');
        
        $checkStrings = [$org, $isp, $asName];
        
        foreach ($this->config['blocked_asn_keywords'] as $keyword) {
            foreach ($checkStrings as $string) {
                if (strpos($string, $keyword) !== false) {
                    return true;
                }
            }
        }
        
        // Check for common VPS/hosting ASNs
        $blockedASNs = [
            'AS14061', 'AS16509', 'AS15169', 'AS8075', 'AS13335', 'AS20473',
            'AS24940', 'AS14618', 'AS19531', 'AS16276', 'AS25820', 'AS63949'
        ];
        
        $asn = $ipInfo['asn'] ?? '';
        if (in_array($asn, $blockedASNs)) {
            return true;
        }
        
        return false;
    }
    
    private function isProxy() {
        // Check for proxy headers
        $proxyHeaders = [
            'HTTP_VIA', 'HTTP_X_FORWARDED_FOR', 'HTTP_FORWARDED_FOR',
            'HTTP_X_FORWARDED', 'HTTP_FORWARDED', 'HTTP_CLIENT_IP',
            'HTTP_FORWARDED_FOR_IP', 'VIA', 'X_FORWARDED_FOR',
            'FORWARDED_FOR', 'X_FORWARDED', 'FORWARDED', 'CLIENT_IP',
            'FORWARDED_FOR_IP', 'HTTP_PROXY_CONNECTION'
        ];
        
        foreach ($proxyHeaders as $header) {
            if (!empty($_SERVER[$header])) {
                return true;
            }
        }
        
        // Check IP against known proxy databases
        $ipInfo = $this->getIPInfo();
        if ($ipInfo && isset($ipInfo['proxy']) && $ipInfo['proxy']) {
            return true;
        }
        
        return false;
    }
    
    private function getIPInfo() {
        static $cache = [];
        
        if (isset($cache[$this->visitorIP])) {
            return $cache[$this->visitorIP];
        }
        
        $apis = [
            "http://ip-api.com/json/{$this->visitorIP}?fields=status,country,countryCode,region,regionName,city,zip,lat,lon,timezone,isp,org,as,asname,proxy,hosting",
            "https://ipapi.co/{$this->visitorIP}/json/",
            "https://ipinfo.io/{$this->visitorIP}/json"
        ];
        
        foreach ($apis as $api) {
            $context = stream_context_create([
                'http' => [
                    'timeout' => 5,
                    'user_agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
                ]
            ]);
            
            $response = @file_get_contents($api, false, $context);
            if ($response) {
                $data = json_decode($response, true);
                if ($data && !empty($data)) {
                    $cache[$this->visitorIP] = $data;
                    return $data;
                }
            }
        }
        
        return null;
    }
    
    private function isAllowedCountry() {
        $ipInfo = $this->getIPInfo();
        if (!$ipInfo) {
            return true; // Allow if we can't determine country
        }
        
        $country = $ipInfo['countryCode'] ?? $ipInfo['country_code'] ?? '';
        return empty($this->config['allowed_countries']) || 
               in_array($country, $this->config['allowed_countries']);
    }
    
    private function isValidFingerprint() {
        // Check for common bot characteristics
        $requiredHeaders = [
            'HTTP_ACCEPT', 'HTTP_ACCEPT_LANGUAGE', 'HTTP_ACCEPT_ENCODING'
        ];
        
        foreach ($requiredHeaders as $header) {
            if (empty($_SERVER[$header])) {
                return false;
            }
        }
        
        // Check for JavaScript capabilities (this would need frontend integration)
        if (empty($_SERVER['HTTP_ACCEPT']) || 
            strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false) {
            return false;
        }
        
        return true;
    }
    
    private function blockAccess($message) {
        $this->logAccess('ACCESS_BLOCKED: ' . $message);
        
        // Send to Telegram if configured
        $this->sendTelegramAlert($message);
        
        // Return 403 Forbidden
        http_response_code(403);
        
        // Show error page
        $this->showErrorPage($message);
        exit;
    }
    
    private function sendTelegramAlert($message) {
        // Integration with existing telegram.php
        if (file_exists('telegram.php')) {
            $alertData = [
                'page' => 'Anti-Bot Alert',
                'action' => 'security_alert',
                'data' => [
                    'ip' => $this->visitorIP,
                    'user_agent' => $this->userAgent,
                    'reason' => $message,
                    'timestamp' => date('Y-m-d H:i:s'),
                    'fingerprint' => $this->fingerprint
                ]
            ];
            
            $context = stream_context_create([
                'http' => [
                    'method' => 'POST',
                    'header' => 'Content-Type: application/json',
                    'content' => json_encode($alertData)
                ]
            ]);
            
            @file_get_contents('telegram.php', false, $context);
        }
    }
    
    private function showErrorPage($message) {
        ?>
        <!DOCTYPE html>
        <html>
        <head>
            <title>Access Denied</title>
            <style>
                body { font-family: Arial, sans-serif; text-align: center; padding: 50px; background: #f5f5f5; }
                .error-container { background: white; padding: 40px; border-radius: 10px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); max-width: 500px; margin: 0 auto; }
                .error-icon { font-size: 64px; color: #e74c3c; margin-bottom: 20px; }
                h1 { color: #2c3e50; margin-bottom: 20px; }
                p { color: #7f8c8d; line-height: 1.6; }
                .error-code { background: #ecf0f1; padding: 10px; border-radius: 5px; font-family: monospace; margin: 20px 0; }
            </style>
        </head>
        <body>
            <div class="error-container">
                <div class="error-icon">🚫</div>
                <h1>Access Denied</h1>
                <p>Your access to this website has been blocked by our security system.</p>
                <div class="error-code">Reason: <?php echo htmlspecialchars($message); ?></div>
                <p>If you believe this is an error, please contact the website administrator.</p>
                <p><small>Reference ID: <?php echo substr($this->fingerprint, 0, 8); ?></small></p>
            </div>
        </body>
        </html>
        <?php
    }
    
    private function logAccess($action) {
        $logEntry = [
            'timestamp' => date('Y-m-d H:i:s'),
            'ip' => $this->visitorIP,
            'action' => $action,
            'user_agent' => $this->userAgent,
            'fingerprint' => substr($this->fingerprint, 0, 16),
            'url' => $_SERVER['REQUEST_URI'] ?? '',
            'referer' => $_SERVER['HTTP_REFERER'] ?? ''
        ];
        
        $logLine = json_encode($logEntry) . "\n";
        file_put_contents($this->logFile, $logLine, FILE_APPEND | LOCK_EX);
    }
    
    public function addToWhitelist($identifier, $reason = '') {
        $entry = $identifier . ' # ' . $reason . ' - ' . date('Y-m-d H:i:s') . "\n";
        file_put_contents($this->whitelistFile, $entry, FILE_APPEND | LOCK_EX);
    }
    
    public function removeFromBlacklist($identifier) {
        $blacklist = file_get_contents($this->blacklistFile);
        $lines = explode("\n", $blacklist);
        $newLines = [];
        
        foreach ($lines as $line) {
            if (strpos($line, $identifier) === false) {
                $newLines[] = $line;
            }
        }
        
        file_put_contents($this->blacklistFile, implode("\n", $newLines));
    }
}

// Initialize and check access
$antiBot = new AdvancedAntiBot();
$antiBot->checkAccess();
?>