<?php
/**
 * ============================================
 * FLOWBOT DCI - POST-DEPLOYMENT VALIDATOR
 * ============================================
 * Validates system integrity after deployment
 *
 * Run: php validate.php
 * ============================================
 */

declare(strict_types=1);

error_reporting(E_ALL);
ini_set('display_errors', '1');

echo "╔══════════════════════════════════════════════════════════════╗\n";
echo "║     FLOWBOT DCI - POST-DEPLOYMENT VALIDATION v1.0           ║\n";
echo "╚══════════════════════════════════════════════════════════════╝\n\n";

$errors = [];
$warnings = [];
$passed = 0;
$total = 0;

function check(string $name, bool $condition, string $errorMsg = ''): void {
    global $errors, $passed, $total;
    $total++;

    if ($condition) {
        echo "✅ PASS: $name\n";
        $passed++;
    } else {
        echo "❌ FAIL: $name\n";
        if ($errorMsg) {
            echo "   └─ $errorMsg\n";
        }
        $errors[] = $name;
    }
}

function warn(string $name, string $msg): void {
    global $warnings;
    echo "⚠️  WARN: $name\n";
    echo "   └─ $msg\n";
    $warnings[] = $name;
}

// ================================================================
// SECTION 1: FILE STRUCTURE VALIDATION
// ================================================================
echo "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
echo "📁 SECTION 1: FILE STRUCTURE VALIDATION\n";
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";

$baseDir = dirname(__DIR__);

$requiredFiles = [
    'index.php',
    'config/config.php',
    '.env.example',
    'src/autoload.php',
    'src/Core/Application.php',
    'src/Core/Database.php',
    'src/Services/RedisService.php',
    'src/Services/WebScraper.php',
    'src/Services/Crawler/DuplicateDetector.php',
    'src/Services/Crawler/UnifiedCrawler.php',
    'src/Models/User.php',
    'views/crawler-ultimate.php',
    'public/index.php',
];

foreach ($requiredFiles as $file) {
    $fullPath = $baseDir . '/' . $file;
    check(
        "File exists: $file",
        file_exists($fullPath),
        "Missing file: $fullPath"
    );
}

$requiredDirs = [
    'src',
    'src/Core',
    'src/Services',
    'src/Services/Crawler',
    'src/Services/SearchEngine',
    'src/Models',
    'src/Api',
    'views',
    'public',
    'config',
    'temp',
    'logs',
];

foreach ($requiredDirs as $dir) {
    $fullPath = $baseDir . '/' . $dir;
    check(
        "Directory exists: $dir",
        is_dir($fullPath),
        "Missing directory: $fullPath"
    );
}

// ================================================================
// SECTION 2: PHP SYNTAX VALIDATION
// ================================================================
echo "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
echo "🔍 SECTION 2: PHP SYNTAX VALIDATION\n";
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";

$phpFiles = [
    'src/Services/RedisService.php',
    'src/Services/Crawler/DuplicateDetector.php',
    'src/Models/User.php',
    'config/config.php',
    'views/crawler-ultimate.php',
];

foreach ($phpFiles as $file) {
    $fullPath = $baseDir . '/' . $file;
    if (file_exists($fullPath)) {
        $output = [];
        $returnCode = 0;
        exec("php -l \"$fullPath\" 2>&1", $output, $returnCode);
        check(
            "Syntax valid: $file",
            $returnCode === 0,
            implode("\n", $output)
        );
    }
}

// ================================================================
// SECTION 3: SECURITY FIXES VALIDATION
// ================================================================
echo "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
echo "🔐 SECTION 3: SECURITY FIXES VALIDATION\n";
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";

// Check DuplicateDetector has whitelist
$duplicateDetector = file_get_contents($baseDir . '/src/Services/Crawler/DuplicateDetector.php');
check(
    "DuplicateDetector: SQL injection fix (ALLOWED_TABLES whitelist)",
    strpos($duplicateDetector, 'ALLOWED_TABLES') !== false,
    "Missing ALLOWED_TABLES constant for SQL injection prevention"
);

check(
    "DuplicateDetector: Table validation implemented",
    strpos($duplicateDetector, "in_array(\$table, self::ALLOWED_TABLES") !== false,
    "Missing table name validation"
);

// Check User.php uses random_bytes
$userModel = file_get_contents($baseDir . '/src/Models/User.php');
check(
    "User model: Secure RNG (random_bytes)",
    strpos($userModel, 'random_bytes') !== false,
    "Still using insecure mt_rand()"
);

check(
    "User model: No mt_rand()",
    strpos($userModel, 'mt_rand()') === false,
    "Found insecure mt_rand() usage"
);

// Check RedisService fail-closed
$redisService = file_get_contents($baseDir . '/src/Services/RedisService.php');
check(
    "RedisService: Fail-closed rate limiting",
    strpos($redisService, 'Fail CLOSED') !== false || strpos($redisService, 'return false;') !== false,
    "Rate limiting may still be fail-open"
);

check(
    "RedisService: No @ error suppression in connect",
    strpos($redisService, '@$this->redis->connect') === false,
    "Found @ error suppression in connect()"
);

// ================================================================
// SECTION 4: CONFIGURATION VALIDATION
// ================================================================
echo "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
echo "⚙️  SECTION 4: CONFIGURATION VALIDATION\n";
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";

// Check config.php is valid
$configPath = $baseDir . '/config/config.php';
if (file_exists($configPath)) {
    try {
        $config = require $configPath;
        check(
            "Config: File loads without errors",
            is_array($config),
            "config.php does not return an array"
        );

        check(
            "Config: Has phases configuration",
            isset($config['phases']) && is_array($config['phases']),
            "Missing or invalid phases configuration"
        );

        check(
            "Config: Has crawler configuration",
            isset($config['crawler']) && is_array($config['crawler']),
            "Missing or invalid crawler configuration"
        );

        check(
            "Config: Has database configuration",
            isset($config['database']) && is_array($config['database']),
            "Missing or invalid database configuration"
        );
    } catch (Throwable $e) {
        check("Config: File loads without errors", false, $e->getMessage());
    }
} else {
    check("Config: File exists", false, "config.php not found");
}

// Check .env exists (or .env.example as fallback)
$envExists = file_exists($baseDir . '/.env');
$envExampleExists = file_exists($baseDir . '/.env.example');
check(
    "Environment: .env or .env.example exists",
    $envExists || $envExampleExists,
    "Neither .env nor .env.example found"
);

if (!$envExists && $envExampleExists) {
    warn("Environment", ".env not found, using .env.example - copy and configure for production");
}

// ================================================================
// SECTION 5: DATABASE CONNECTIVITY (Optional)
// ================================================================
echo "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
echo "🗄️  SECTION 5: DATABASE CONNECTIVITY\n";
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";

try {
    require_once $baseDir . '/src/autoload.php';

    if (file_exists($baseDir . '/.env')) {
        $envContent = file_get_contents($baseDir . '/.env');
        preg_match('/DB_HOST=(.*)/', $envContent, $hostMatch);
        preg_match('/DB_NAME=(.*)/', $envContent, $nameMatch);
        preg_match('/DB_USER=(.*)/', $envContent, $userMatch);
        preg_match('/DB_PASS=(.*)/', $envContent, $passMatch);

        if ($hostMatch && $nameMatch && $userMatch) {
            $host = trim($hostMatch[1] ?? 'localhost');
            $name = trim($nameMatch[1] ?? '');
            $user = trim($userMatch[1] ?? '');
            $pass = trim($passMatch[1] ?? '');

            try {
                $pdo = new PDO(
                    "mysql:host=$host;dbname=$name;charset=utf8mb4",
                    $user,
                    $pass,
                    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
                );
                check("Database: Connection successful", true);

                // Check required tables
                $tables = ['pinfeeds', 'user_myhashtag', 'crawler_jobs'];
                foreach ($tables as $table) {
                    $stmt = $pdo->query("SHOW TABLES LIKE '$table'");
                    check(
                        "Database: Table '$table' exists",
                        $stmt->rowCount() > 0,
                        "Table $table not found"
                    );
                }
            } catch (PDOException $e) {
                warn("Database", "Connection failed: " . $e->getMessage());
            }
        } else {
            warn("Database", "Database credentials not found in .env");
        }
    } else {
        warn("Database", ".env not found, skipping database checks");
    }
} catch (Throwable $e) {
    warn("Database", "Error loading autoload: " . $e->getMessage());
}

// ================================================================
// SECTION 6: VIEWS/UI VALIDATION
// ================================================================
echo "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
echo "🖼️  SECTION 6: VIEWS/UI VALIDATION\n";
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";

$viewFiles = [
    'views/crawler-ultimate.php',
    'public/dashboard.php',
];

foreach ($viewFiles as $file) {
    $fullPath = $baseDir . '/' . $file;
    if (file_exists($fullPath)) {
        $content = file_get_contents($fullPath);

        // Check for map-related code
        $hasMap = strpos($content, 'map') !== false ||
                  strpos($content, 'leaflet') !== false ||
                  strpos($content, 'google.maps') !== false ||
                  strpos($content, 'mapbox') !== false;

        // Check for chart-related code
        $hasCharts = strpos($content, 'Chart') !== false ||
                     strpos($content, 'chart') !== false ||
                     strpos($content, 'graph') !== false ||
                     strpos($content, 'echarts') !== false ||
                     strpos($content, 'chartjs') !== false;

        // Check for stats/metrics code
        $hasStats = strpos($content, 'stats') !== false ||
                    strpos($content, 'metrics') !== false ||
                    strpos($content, 'statistics') !== false;

        if ($hasMap) {
            check("UI ($file): Map functionality present", true);
        }
        if ($hasCharts) {
            check("UI ($file): Chart functionality present", true);
        }
        if ($hasStats) {
            check("UI ($file): Statistics/metrics present", true);
        }
    }
}

// Check crawler-ultimate.php specific features
$crawlerUltimate = file_get_contents($baseDir . '/views/crawler-ultimate.php');

check(
    "Crawler Ultimate: Viral mode function exists",
    strpos($crawlerUltimate, 'runViralMode') !== false,
    "runViralMode function not found"
);

check(
    "Crawler Ultimate: SSE events support",
    strpos($crawlerUltimate, 'text/event-stream') !== false ||
    strpos($crawlerUltimate, 'Server-Sent Events') !== false,
    "SSE support not found"
);

check(
    "Crawler Ultimate: Multi-process support",
    strpos($crawlerUltimate, 'MP_MAX_PROCESSES') !== false,
    "Multi-process constants not found"
);

// ================================================================
// SUMMARY
// ================================================================
echo "\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
echo "📊 VALIDATION SUMMARY\n";
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n";

echo "Total checks: $total\n";
echo "Passed:       $passed (" . round(($passed / $total) * 100) . "%)\n";
echo "Failed:       " . count($errors) . "\n";
echo "Warnings:     " . count($warnings) . "\n\n";

if (count($errors) > 0) {
    echo "❌ FAILED CHECKS:\n";
    foreach ($errors as $error) {
        echo "   • $error\n";
    }
    echo "\n";
}

if (count($warnings) > 0) {
    echo "⚠️  WARNINGS:\n";
    foreach ($warnings as $warning) {
        echo "   • $warning\n";
    }
    echo "\n";
}

if (count($errors) === 0) {
    echo "╔══════════════════════════════════════════════════════════════╗\n";
    echo "║              ✅ ALL VALIDATIONS PASSED!                     ║\n";
    echo "║         System is ready for production deployment           ║\n";
    echo "╚══════════════════════════════════════════════════════════════╝\n";
    exit(0);
} else {
    echo "╔══════════════════════════════════════════════════════════════╗\n";
    echo "║              ❌ VALIDATION FAILED                           ║\n";
    echo "║         Please fix the issues above before deploying        ║\n";
    echo "╚══════════════════════════════════════════════════════════════╝\n";
    exit(1);
}
