<?php
/**
 * Security Functions
 * Fungsi-fungsi keamanan untuk aplikasi
 */

// XSS Protection - Escape output
function e($string) {
    return htmlspecialchars($string ?? '', ENT_QUOTES, 'UTF-8');
}

// Validate email
function validate_email($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL);
}

// Sanitize filename untuk upload
function sanitize_filename($filename) {
    // Remove special characters
    $filename = preg_replace('/[^a-zA-Z0-9._-]/', '', $filename);
    // Limit length
    return substr($filename, 0, 255);
}

// Validate image upload
function validate_image_upload($file) {
    $allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
    $max_size = 5 * 1024 * 1024; // 5MB
    
    // Check upload error
    if ($file['error'] !== UPLOAD_ERR_OK) {
        return ['success' => false, 'error' => 'Upload error: ' . $file['error']];
    }
    
    // Check file size
    if ($file['size'] > $max_size) {
        return ['success' => false, 'error' => 'File terlalu besar (maksimal 5MB)'];
    }
    
    // Check MIME type
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime = finfo_file($finfo, $file['tmp_name']);
    finfo_close($finfo);
    
    if (!in_array($mime, $allowed_types)) {
        return ['success' => false, 'error' => 'Tipe file tidak diizinkan. Hanya JPG, PNG, GIF, WEBP'];
    }
    
    // Verify it's really an image
    if (!getimagesize($file['tmp_name'])) {
        return ['success' => false, 'error' => 'File bukan gambar yang valid'];
    }
    
    return ['success' => true];
}

// Rate limiting untuk login
function check_rate_limit($identifier, $max_attempts = 5, $window = 900) {
    $data_dir = __DIR__ . '/../data';
    if (!is_dir($data_dir)) mkdir($data_dir, 0755, true);
    
    $cache_file = $data_dir . '/rate_limit_' . md5($identifier) . '.json';
    
    if (file_exists($cache_file)) {
        $data = json_decode(file_get_contents($cache_file), true);
        
        // Check if within time window
        if (time() - $data['time'] < $window) {
            if ($data['attempts'] >= $max_attempts) {
                $remaining = $window - (time() - $data['time']);
                return [
                    'allowed' => false,
                    'remaining_time' => $remaining,
                    'message' => 'Terlalu banyak percobaan. Coba lagi dalam ' . ceil($remaining / 60) . ' menit.'
                ];
            }
            $data['attempts']++;
        } else {
            // Reset counter
            $data = ['time' => time(), 'attempts' => 1];
        }
    } else {
        $data = ['time' => time(), 'attempts' => 1];
    }
    
    file_put_contents($cache_file, json_encode($data));
    return ['allowed' => true, 'attempts' => $data['attempts']];
}

// Reset rate limit (after successful login)
function reset_rate_limit($identifier) {
    $data_dir = __DIR__ . '/../data';
    $cache_file = $data_dir . '/rate_limit_' . md5($identifier) . '.json';
    if (file_exists($cache_file)) {
        unlink($cache_file);
    }
}

// Password strength validation
function validate_password_strength($password) {
    if (strlen($password) < 8) {
        return ['valid' => false, 'error' => 'Password minimal 8 karakter'];
    }
    if (!preg_match('/[A-Z]/', $password)) {
        return ['valid' => false, 'error' => 'Password harus mengandung minimal 1 huruf besar'];
    }
    if (!preg_match('/[a-z]/', $password)) {
        return ['valid' => false, 'error' => 'Password harus mengandung minimal 1 huruf kecil'];
    }
    if (!preg_match('/[0-9]/', $password)) {
        return ['valid' => false, 'error' => 'Password harus mengandung minimal 1 angka'];
    }
    return ['valid' => true];
}

// Generate secure random token
function generate_token($length = 32) {
    return bin2hex(random_bytes($length));
}

// Clean old rate limit files (cleanup)
function cleanup_rate_limits($max_age = 86400) {
    $data_dir = __DIR__ . '/../data';
    $files = glob($data_dir . '/rate_limit_*.json');
    
    foreach ($files as $file) {
        if (filemtime($file) < time() - $max_age) {
            unlink($file);
        }
    }
}
?>
