<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Performance Helper
 * 
 * Provides caching and performance optimization functions
 */

if (!function_exists('cache_query')) {
    /**
     * Cache database query results
     * 
     * @param string $cache_key Unique cache key
     * @param callable $query_function Function that returns query result
     * @param int $cache_time Cache time in seconds (default: 300 = 5 minutes)
     * @return mixed Query result
     */
    function cache_query($cache_key, $query_function, $cache_time = 300) {
        $CI =& get_instance();
        $CI->load->driver('cache', array('adapter' => 'file'));
        
        // Try to get from cache first
        $cached_result = $CI->cache->get($cache_key);
        
        if ($cached_result !== FALSE) {
            return $cached_result;
        }
        
        // Execute query and cache result
        $result = $query_function();
        $CI->cache->save($cache_key, $result, $cache_time);
        
        return $result;
    }
}

if (!function_exists('clear_cache')) {
    /**
     * Clear specific cache or all cache
     * 
     * @param string $cache_key Optional specific cache key to clear
     */
    function clear_cache($cache_key = NULL) {
        $CI =& get_instance();
        $CI->load->driver('cache', array('adapter' => 'file'));
        
        if ($cache_key) {
            $CI->cache->delete($cache_key);
        } else {
            $CI->cache->clean();
        }
    }
}

if (!function_exists('optimize_query')) {
    /**
     * Optimize database query with proper indexing hints
     * 
     * @param string $table Table name
     * @param array $where Where conditions
     * @param string $select Fields to select
     * @param string $order_by Order by clause
     * @param int $limit Limit
     * @return object Query result
     */
    function optimize_query($table, $where = array(), $select = '*', $order_by = '', $limit = 0) {
        $CI =& get_instance();
        
        // Use proper indexing
        if (!empty($where)) {
            foreach ($where as $field => $value) {
                $CI->db->where($field, $value);
            }
        }
        
        if ($select !== '*') {
            $CI->db->select($select);
        }
        
        if (!empty($order_by)) {
            $CI->db->order_by($order_by);
        }
        
        if ($limit > 0) {
            $CI->db->limit($limit);
        }
        
        return $CI->db->get($table);
    }
}

if (!function_exists('batch_insert')) {
    /**
     * Insert multiple records efficiently
     * 
     * @param string $table Table name
     * @param array $data Array of data to insert
     * @return bool Success status
     */
    function batch_insert($table, $data) {
        $CI =& get_instance();
        
        if (empty($data)) {
            return FALSE;
        }
        
        // Use batch insert for better performance
        return $CI->db->insert_batch($table, $data);
    }
}

if (!function_exists('get_memory_usage')) {
    /**
     * Get current memory usage
     * 
     * @return string Formatted memory usage
     */
    function get_memory_usage() {
        $memory = memory_get_usage(TRUE);
        $peak = memory_get_peak_usage(TRUE);
        
        return array(
            'current' => format_bytes($memory),
            'peak' => format_bytes($peak)
        );
    }
}

if (!function_exists('format_bytes')) {
    /**
     * Format bytes to human readable format
     * 
     * @param int $bytes Number of bytes
     * @return string Formatted string
     */
    function format_bytes($bytes) {
        $units = array('B', 'KB', 'MB', 'GB');
        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);
        
        $bytes /= pow(1024, $pow);
        
        return round($bytes, 2) . ' ' . $units[$pow];
    }
}

if (!function_exists('get_query_time')) {
    /**
     * Get query execution time
     * 
     * @param callable $query_function Query function to execute
     * @return array Query time and result
     */
    function get_query_time($query_function) {
        $start_time = microtime(TRUE);
        $result = $query_function();
        $end_time = microtime(TRUE);
        
        return array(
            'time' => round(($end_time - $start_time) * 1000, 2) . 'ms',
            'result' => $result
        );
    }
}

if (!function_exists('minify_output')) {
    /**
     * Minify HTML output
     * 
     * @param string $output HTML output
     * @return string Minified HTML
     */
    function minify_output($output) {
        // Remove extra whitespace
        $output = preg_replace('/\s+/', ' ', $output);
        $output = preg_replace('/>\s+</', '><', $output);
        
        return trim($output);
    }
}
