<?php
/**
 * Permission Checker Functions
 * Provides functions to check permissions and handle unauthorized access
 */

require_once('/docker/whp/web/libs/permission_manager.php');
require_once('/docker/whp/web/libs/network.php');

/**
 * Check if user has permission to access the current page
 * If not, log the attempt and redirect to dashboard with error message
 */
function check_page_permission() {
    // Only check if AUTH_USER is defined (user is authenticated)
    if (!defined('AUTH_USER')) {
        return;
    }
    
    $user = AUTH_USER;
    $page = isset($_GET['page']) ? $_GET['page'] : 'dashboard';
    
    // Initialize permission manager and network info
    $PermManager = new permission_manager();
    $NetInfo = new network_info();
    
    // Check permission
    $has_permission = $PermManager->check_page_permission($user, $page);
    
    // Get client info for logging
    $ip_address = $NetInfo->get_client_ip();
    $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
    
    if (!$has_permission) {
        // Log the denied access attempt
        $reason = "User {$user} does not have permission to access {$page}";
        $PermManager->log_access_attempt($user, $page, $ip_address, $user_agent, false, $reason);
        
        // Set error message in session
        $denial_message = $PermManager->get_denial_message($page, $user);
        $_SESSION['permission_error'] = $denial_message;
        
        // Redirect to dashboard
        header('Location: index.php');
        exit();
    } else {
        // Log successful access attempt
        $PermManager->log_access_attempt($user, $page, $ip_address, $user_agent, true);
    }
}

/**
 * Check if user has permission to access an API
 * If not, return JSON error response
 */
function check_api_permission($api_name) {
    // Only check if AUTH_USER is defined (user is authenticated)
    if (!defined('AUTH_USER')) {
        http_response_code(401);
        echo json_encode(array(
            'status' => 'error',
            'message' => 'Authentication required'
        ));
        exit();
    }
    
    $user = AUTH_USER;
    
    // Initialize permission manager and network info
    $PermManager = new permission_manager();
    $NetInfo = new network_info();
    
    // Check permission
    $has_permission = $PermManager->check_api_permission($user, $api_name);
    
    // Get client info for logging
    $ip_address = $NetInfo->get_client_ip();
    $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
    
    if (!$has_permission) {
        // Log the denied access attempt
        $reason = "User {$user} does not have permission to access API {$api_name}";
        $PermManager->log_access_attempt($user, $api_name, $ip_address, $user_agent, false, $reason);
        
        // Return JSON error
        http_response_code(403);
        echo json_encode(array(
            'status' => 'error',
            'message' => 'Access denied. Insufficient privileges.'
        ));
        exit();
    } else {
        // Log successful access attempt
        $PermManager->log_access_attempt($user, $api_name, $ip_address, $user_agent, true);
    }
}

/**
 * Display permission error message if one exists in session
 */
function display_permission_error() {
    if (isset($_SESSION['permission_error'])) {
        $error_message = $_SESSION['permission_error'];
        unset($_SESSION['permission_error']); // Clear the message after displaying
        
        echo '<div class="row">';
        echo '<div class="col-sm-12">';
        echo '<div class="alert alert-danger alert-dismissible" role="alert">';
        echo '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>';
        echo '<i class="fa fa-exclamation-triangle"></i> ';
        echo htmlspecialchars($error_message);
        echo '</div>';
        echo '</div>';
        echo '</div>';
    }
}

/**
 * Get access statistics for the current user
 */
function get_user_access_statistics($days = 30) {
    if (!defined('AUTH_USER')) {
        return null;
    }
    
    $PermManager = new permission_manager();
    return $PermManager->get_user_access_stats(AUTH_USER, $days);
}

/**
 * Get system-wide access statistics (root only)
 */
function get_system_access_statistics($days = 30) {
    if (!defined('AUTH_USER') || AUTH_USER !== 'root') {
        return null;
    }
    
    $PermManager = new permission_manager();
    return $PermManager->get_system_access_stats($days);
}

/**
 * Check if user has permission to access a specific domain
 * 
 * @param string $domain The domain name
 * @return bool True if user has permission, false otherwise
 */
function check_domain_permission($domain) {
    if (!defined('AUTH_USER')) {
        return false;
    }
    
    $PermManager = new permission_manager();
    return $PermManager->check_domain_ownership(AUTH_USER, $domain);
}

/**
 * Get domains owned by the current user
 * 
 * @return array Array of domain names owned by the user
 */
function get_user_domains() {
    if (!defined('AUTH_USER')) {
        return array();
    }
    
    $PermManager = new permission_manager();
    return $PermManager->get_user_domains(AUTH_USER);
}

/**
 * Check if user is root
 *
 * @return bool True if user is root, false otherwise
 */
function is_root_user() {
    return defined('AUTH_USER') && AUTH_USER === 'root';
}

/**
 * Whether the given user owns the given site (or is root).
 *
 * Internal helper used by Issue and Suppression permission checks.
 * Queries whp.sites for ownership; caches results within a single request
 * to avoid repeated queries when rendering lists.
 *
 * @param int $site_id
 * @param string $username
 * @return bool
 */
function can_view_site(int $site_id, string $username): bool {
    if ($username === 'root') return true;
    if ($site_id <= 0) return false;

    static $cache = [];
    $key = $site_id . '|' . $username;
    if (array_key_exists($key, $cache)) return $cache[$key];

    try {
        require_once('/docker/whp/web/libs/mysqlmgmt.php');
        $db = (new mysqlmgmt())->getMySQLConnection();
        if (!$db) {
            error_log('can_view_site: mysqlmgmt::getMySQLConnection returned false');
            $cache[$key] = false;
            return false;
        }
        $stmt = $db->prepare('SELECT 1 FROM whp.sites WHERE id = ? AND username = ? LIMIT 1');
        $stmt->execute([$site_id, $username]);
        $cache[$key] = (bool)$stmt->fetchColumn();
    } catch (Throwable $e) {
        error_log('can_view_site: ' . $e->getMessage());
        $cache[$key] = false;
    }
    return $cache[$key];
}

/**
 * Whether the given user can view an Issue row.
 *
 * Root can view any Issue. Non-root can only view Issues whose site_id is
 * owned by them. Server-wide Issues (site_id IS NULL or 0) are never
 * visible to non-root.
 *
 * @param array $issue  Issue row with at least 'site_id' key (may be null).
 * @param string $username
 * @return bool
 */
function can_view_issue(array $issue, string $username): bool {
    if ($username === 'root') return true;
    if (empty($issue['site_id'])) return false; // server-wide
    return can_view_site((int)$issue['site_id'], $username);
}

/**
 * Whether the given user can modify (mark fixed, ignore, un-suppress) an
 * Issue row. Same rules as can_view_issue.
 *
 * @param array $issue
 * @param string $username
 * @return bool
 */
function can_modify_issue(array $issue, string $username): bool {
    return can_view_issue($issue, $username);
} 