<?php
/**
 * Sphinx Search Indexer Wrapper with Real-time Progress and Permission Handling
 * Recommended usage: php lib/plugins/sphinxsearchwas/indexer.php
 */

// 1. Setup DokuWiki environment
if (!defined('DOKU_INC')) {
    $inc_path = realpath(__DIR__ . '/../../../') . '/';
    if (!file_exists($inc_path . 'inc/init.php')) {
        die("Error: Could not find DokuWiki core. Run this script from within the plugin directory.\n");
    }
    define('DOKU_INC', $inc_path);
}

define('NOSESSION', 1);
require_once(DOKU_INC . 'inc/init.php');

if (PHP_SAPI !== 'cli') {
    header('HTTP/1.1 403 Forbidden');
    die("Access Denied: This script must be run from the command line.\n");
}

// 2. Load Plugin Configuration
/** @var action_plugin_sphinxsearchwas $plugin */
$plugin = plugin_load('action', 'sphinxsearchwas');
if (!$plugin) {
    die("Error: Sphinxsearch plugin is not installed or enabled.\n");
}

$indexName = $plugin->getConf('index') ?: 'dk_main';
$configFile = __DIR__ . '/sphinx.conf';
$indexerBin = 'indexer';
$targetUser = 'www-data';
$targetGroup = 'www-data';

// 3. Directory Validation
if (!file_exists($configFile)) {
    die("Error: Sphinx configuration file not found at $configFile\n");
}

$idxPath = DOKU_INC . 'data/sphinxsearchwas';
if (!is_dir($idxPath)) {
    mkdir($idxPath, 0777, true);
}

// 4. CHANGE DIRECTORY: Resolve paths relative to DokuWiki Root
chdir(DOKU_INC);

// 5. Build Command
$cmd = sprintf(
    '%s -c %s --rotate %s 2>&1',
    $indexerBin,
    escapeshellarg($configFile),
    escapeshellarg($indexName)
);

echo "Starting Sphinx Indexer for index: $indexName...\n";
echo "Working Directory: " . getcwd() . "\n";
echo "--------------------------------------------------\n";

// 6. Execute and Stream Output
$handle = popen($cmd, 'r');

if ($handle) {
    while (!feof($handle)) {
        $line = fgets($handle);
        if ($line !== false) {
            echo $line;
            if (ob_get_level() > 0) ob_flush();
            flush();
        }
    }
    $returnCode = pclose($handle);
} else {
    echo "Error: Failed to execute indexer binary.\n";
    $returnCode = 1;
}

// 7. Post-Indexing: Permission and Ownership Update
if ($returnCode === 0) {
    echo "--------------------------------------------------\n";
    echo "Updating file ownership and permissions in $idxPath...\n";

    try {
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($idxPath, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::SELF_FIRST
        );

        // Also process the root directory itself
        $paths = iterator_to_array($iterator);
        $paths[] = new SplFileInfo($idxPath);

        foreach ($paths as $fileInfo) {
            $path = $fileInfo->getRealPath();

            // Set Ownership
            if (!@chown($path, $targetUser)) {
                echo "Warning: Could not change owner of $path to $targetUser\n";
            }
            if (!@chgrp($path, $targetGroup)) {
                echo "Warning: Could not change group of $path to $targetGroup\n";
            }

            // Set Access Flags
            if (is_dir($path)) {
                chmod($path, 0775); // rwxrwxr-x
            } else {
                chmod($path, 0664); // rw-rw-r--
            }
        }
        echo "[SUCCESS] Permissions and ownership updated to $targetUser:$targetGroup.\n";
    } catch (Exception $e) {
        echo "[ERROR] Failed to update permissions: " . $e->getMessage() . "\n";
    }
}

// 8. Final Report
echo "--------------------------------------------------\n";
if ($returnCode === 0) {
    echo "[SUCCESS] Indexing completed successfully.\n";
    exit(0);
} else {
    echo "[ERROR] Indexing failed with exit code: $returnCode\n";
    exit($returnCode);
}
