/**
 * Descomplicar® Crescimento Digital
 * https://descomplicar.pt
 */

<?php

/**
 * PHPUnit Bootstrap for Desk-Moloni Integration Tests
 * 
 * Sets up test environment for OAuth and API client testing
 * 
 * @package     DeskMoloni
 * @author      Descomplicar®
 * @copyright   2025 Descomplicar
 * @version     3.0.0
 */

// Prevent direct access
defined('BASEPATH') or define('BASEPATH', true);

// Set test environment
define('ENVIRONMENT', 'testing');
define('DESK_MOLONI_TEST_MODE', true);

// Error reporting for tests
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);

// Set timezone
date_default_timezone_set('Europe/Lisbon');

// Define paths
define('FCPATH', realpath(dirname(__FILE__) . '/../../../../') . '/');
define('APPPATH', FCPATH . 'application/');
define('VIEWPATH', APPPATH . 'views/');
define('BASEPATH', FCPATH . 'system/');

// Load Composer autoloader if available
if (file_exists(FCPATH . 'vendor/autoload.php')) {
    require_once FCPATH . 'vendor/autoload.php';
}

// Mock CodeIgniter functions for testing
if (!function_exists('get_instance')) {
    function &get_instance() {
        return DeskMoloniTestFramework::getInstance();
    }
}

if (!function_exists('get_option')) {
    function get_option($option_name, $default = '') {
        return DeskMoloniTestFramework::getOption($option_name, $default);
    }
}

if (!function_exists('update_option')) {
    function update_option($option_name, $option_value) {
        return DeskMoloniTestFramework::updateOption($option_name, $option_value);
    }
}

if (!function_exists('log_activity')) {
    function log_activity($message) {
        DeskMoloniTestFramework::logActivity($message);
    }
}

if (!function_exists('admin_url')) {
    function admin_url($path = '') {
        return 'https://test.example.com/admin/' . ltrim($path, '/');
    }
}

if (!function_exists('has_permission')) {
    function has_permission($module, $capability = '', $staff_id = '') {
        return true; // Allow all permissions in tests
    }
}

if (!function_exists('get_staff_full_name')) {
    function get_staff_full_name($staff_id = '') {
        return 'Test User';
    }
}

if (!function_exists('get_staff_user_id')) {
    function get_staff_user_id() {
        return 1;
    }
}

if (!function_exists('set_alert')) {
    function set_alert($type, $message) {
        DeskMoloniTestFramework::setAlert($type, $message);
    }
}

if (!function_exists('redirect')) {
    function redirect($uri = '', $method = 'auto', $code = NULL) {
        // In tests, we don't actually redirect
        DeskMoloniTestFramework::$last_redirect = $uri;
    }
}

/**
 * Test Framework Helper Class
 * 
 * Provides mock implementations of CodeIgniter functionality for testing
 */
class DeskMoloniTestFramework
{
    private static $instance;
    private static $options = [];
    private static $activity_log = [];
    private static $alerts = [];
    public static $last_redirect = '';
    
    private $libraries = [];
    private $models = [];
    private $session_data = [];
    
    public function __construct()
    {
        // Initialize mock session
        $this->session_data = [];
        
        // Initialize mock security
        $this->security = new MockSecurity();
        
        // Initialize mock session
        $this->session = new MockSession($this->session_data);
        
        // Initialize mock input
        $this->input = new MockInput();
        
        // Initialize mock output
        $this->output = new MockOutput();
        
        // Initialize mock load
        $this->load = new MockLoader($this);
    }
    
    public static function &getInstance()
    {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    public static function getOption($name, $default = '')
    {
        return self::$options[$name] ?? $default;
    }
    
    public static function updateOption($name, $value)
    {
        self::$options[$name] = $value;
        return true;
    }
    
    public static function logActivity($message)
    {
        self::$activity_log[] = [
            'message' => $message,
            'timestamp' => date('Y-m-d H:i:s')
        ];
    }
    
    public static function setAlert($type, $message)
    {
        self::$alerts[] = [
            'type' => $type,
            'message' => $message
        ];
    }
    
    public static function reset()
    {
        self::$options = [];
        self::$activity_log = [];
        self::$alerts = [];
        self::$last_redirect = '';
        self::$instance = null;
    }
    
    public static function getActivityLog()
    {
        return self::$activity_log;
    }
    
    public static function getAlerts()
    {
        return self::$alerts;
    }
    
    public function library($name)
    {
        return $this->libraries[$name] ?? null;
    }
    
    public function setLibrary($name, $instance)
    {
        $this->libraries[$name] = $instance;
    }
}

/**
 * Mock CodeIgniter Classes for Testing
 */
class MockSecurity
{
    private $csrf_hash = 'test_csrf_token';
    
    public function get_csrf_hash()
    {
        return $this->csrf_hash;
    }
    
    public function get_csrf_token_name()
    {
        return 'csrf_test_name';
    }
}

class MockSession
{
    private $data;
    
    public function __construct(&$data)
    {
        $this->data = &$data;
    }
    
    public function userdata($key = null)
    {
        if ($key === null) {
            return $this->data;
        }
        return $this->data[$key] ?? null;
    }
    
    public function set_userdata($key, $value = null)
    {
        if (is_array($key)) {
            foreach ($key as $k => $v) {
                $this->data[$k] = $v;
            }
        } else {
            $this->data[$key] = $value;
        }
    }
    
    public function unset_userdata($key)
    {
        if (is_array($key)) {
            foreach ($key as $k) {
                unset($this->data[$k]);
            }
        } else {
            unset($this->data[$key]);
        }
    }
}

class MockInput
{
    private $get_data = [];
    private $post_data = [];
    
    public function get($key = null, $xss_clean = null)
    {
        if ($key === null) {
            return $this->get_data;
        }
        return $this->get_data[$key] ?? null;
    }
    
    public function post($key = null, $xss_clean = null)
    {
        if ($key === null) {
            return $this->post_data;
        }
        return $this->post_data[$key] ?? null;
    }
    
    public function is_ajax_request()
    {
        return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && 
               strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
    }
    
    public function setGetData($data)
    {
        $this->get_data = $data;
    }
    
    public function setPostData($data)
    {
        $this->post_data = $data;
    }
}

class MockOutput
{
    private $headers = [];
    private $content_type = 'text/html';
    private $status_code = 200;
    
    public function set_content_type($type)
    {
        $this->content_type = $type;
        return $this;
    }
    
    public function set_header($header)
    {
        $this->headers[] = $header;
        return $this;
    }
    
    public function set_status_header($code)
    {
        $this->status_code = $code;
        return $this;
    }
    
    public function set_output($output)
    {
        // In tests, we don't actually output
        return $this;
    }
    
    public function getHeaders()
    {
        return $this->headers;
    }
    
    public function getContentType()
    {
        return $this->content_type;
    }
    
    public function getStatusCode()
    {
        return $this->status_code;
    }
}

class MockLoader
{
    private $ci;
    
    public function __construct($ci)
    {
        $this->ci = $ci;
    }
    
    public function library($library, $params = NULL, $object_name = NULL)
    {
        // Mock library loading
        $library_name = strtolower($library);
        
        // Handle Desk-Moloni specific libraries
        if (strpos($library_name, 'desk_moloni/') === 0) {
            $class_name = str_replace('desk_moloni/', '', $library_name);
            $class_name = ucfirst($class_name);
            
            // Load the actual library file for testing
            $library_path = dirname(__DIR__) . '/libraries/' . $class_name . '.php';
            if (file_exists($library_path)) {
                require_once $library_path;
                
                if (class_exists($class_name)) {
                    $instance = new $class_name($params);
                    $property_name = $object_name ?: strtolower($class_name);
                    $this->ci->$property_name = $instance;
                    $this->ci->setLibrary($property_name, $instance);
                }
            }
        }
        
        return true;
    }
    
    public function model($model, $name = '', $db_conn = FALSE)
    {
        // Mock model loading
        return true;
    }
    
    public function helper($helpers)
    {
        // Mock helper loading
        return true;
    }
    
    public function view($view, $vars = array(), $return = FALSE)
    {
        // Mock view loading
        if ($return) {
            return '<html>Mock View: ' . $view . '</html>';
        }
    }
}

// Initialize test framework
DeskMoloniTestFramework::getInstance();

// Set up test-specific options
DeskMoloniTestFramework::updateOption('desk_moloni_encryption_key', base64_encode(random_bytes(32)));

echo "Desk-Moloni Test Environment Initialized\n";