<?php

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

// Set content type to JSON
header('Content-Type: application/json');

// Initialize managers
$delegatedUserManager = new DelegatedUserManager();
$permissionManager = new permission_manager();

// Check authentication
if (!isset($_SESSION['user'])) {
    http_response_code(401);
    echo json_encode(['success' => false, 'message' => 'Authentication required']);
    exit;
}

// Delegated sessions run under the PARENT username, so $current_user would
// pass every ownership check below — letting a delegated user create, alter,
// or delete delegated users (and their permission flags) for the whole
// account. Only system sessions may use this endpoint.
if (($_SESSION['user_type'] ?? '') !== 'system') {
    http_response_code(403);
    echo json_encode(['success' => false, 'message' => 'Delegated sessions cannot manage delegated users']);
    exit;
}

$current_user = $_SESSION['user'];
$action = $_GET['action'] ?? '';

// Log the API access attempt (trusted-proxy-aware client IP — REMOTE_ADDR is
// the HAProxy address behind the proxy, useless for forensics)
$permissionManager->log_access_attempt($current_user, 'delegated-user-management',
    (new network_info())->get_client_ip(), $_SERVER['HTTP_USER_AGENT'] ?? '', true, 'API access');

try {
    switch ($action) {
        case 'create':
            if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
                http_response_code(405);
                echo json_encode(['success' => false, 'message' => 'Method not allowed']);
                exit;
            }
            
            // Get POST data
            $input = json_decode(file_get_contents('php://input'), true);
            
            if (!$input) {
                http_response_code(400);
                echo json_encode(['success' => false, 'message' => 'Invalid JSON input']);
                exit;
            }
            
            // Validate required fields
            $required_fields = ['username', 'password', 'parent_username'];
            foreach ($required_fields as $field) {
                if (empty($input[$field])) {
                    http_response_code(400);
                    echo json_encode(['success' => false, 'message' => "Field '$field' is required"]);
                    exit;
                }
            }
            
            // Check if user can create delegated users for the specified parent
            if ($current_user !== 'root' && $current_user !== $input['parent_username']) {
                http_response_code(403);
                echo json_encode(['success' => false, 'message' => 'Not authorized to create delegated users for this account']);
                exit;
            }
            
            $result = $delegatedUserManager->createDelegatedUser($input, $current_user);
            
            if ($result['success']) {
                http_response_code(201);
            } else {
                http_response_code(400);
            }
            echo json_encode($result);
            break;
            
        case 'list':
            $parent_username = $_GET['parent_username'] ?? $current_user;
            $include_inactive = filter_var($_GET['include_inactive'] ?? false, FILTER_VALIDATE_BOOLEAN);
            
            // Check if user can view delegated users for the specified parent
            if ($current_user !== 'root' && $current_user !== $parent_username) {
                http_response_code(403);
                echo json_encode(['success' => false, 'message' => 'Not authorized to view delegated users for this account']);
                exit;
            }
            
            $users = $delegatedUserManager->getDelegatedUsers($parent_username, $include_inactive);
            echo json_encode(['success' => true, 'users' => $users]);
            break;
            
        case 'update':
            if ($_SERVER['REQUEST_METHOD'] !== 'PUT') {
                http_response_code(405);
                echo json_encode(['success' => false, 'message' => 'Method not allowed']);
                exit;
            }
            
            $user_id = intval($_GET['user_id'] ?? 0);
            if (!$user_id) {
                http_response_code(400);
                echo json_encode(['success' => false, 'message' => 'User ID is required']);
                exit;
            }
            
            // Get PUT data
            $input = json_decode(file_get_contents('php://input'), true);
            
            if (!$input) {
                http_response_code(400);
                echo json_encode(['success' => false, 'message' => 'Invalid JSON input']);
                exit;
            }
            
            $result = $delegatedUserManager->updateDelegatedUser($user_id, $input, $current_user);
            
            if ($result['success']) {
                http_response_code(200);
            } else {
                http_response_code(400);
            }
            echo json_encode($result);
            break;
            
        case 'delete':
            if ($_SERVER['REQUEST_METHOD'] !== 'DELETE') {
                http_response_code(405);
                echo json_encode(['success' => false, 'message' => 'Method not allowed']);
                exit;
            }
            
            $user_id = intval($_GET['user_id'] ?? 0);
            if (!$user_id) {
                http_response_code(400);
                echo json_encode(['success' => false, 'message' => 'User ID is required']);
                exit;
            }
            
            $result = $delegatedUserManager->deleteDelegatedUser($user_id, $current_user);
            
            if ($result['success']) {
                http_response_code(200);
            } else {
                http_response_code(400);
            }
            echo json_encode($result);
            break;
            
        case 'change_password':
            if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
                http_response_code(405);
                echo json_encode(['success' => false, 'message' => 'Method not allowed']);
                exit;
            }
            
            $input = json_decode(file_get_contents('php://input'), true);
            
            if (!$input || empty($input['user_id']) || empty($input['new_password'])) {
                http_response_code(400);
                echo json_encode(['success' => false, 'message' => 'User ID and new password are required']);
                exit;
            }
            
            $user_id = intval($input['user_id']);
            $new_password = $input['new_password'];
            
            // Validate password strength
            if (strlen($new_password) < 8) {
                http_response_code(400);
                echo json_encode(['success' => false, 'message' => 'Password must be at least 8 characters long']);
                exit;
            }
            
            // Hash the new password
            $password_hash = password_hash($new_password, PASSWORD_ARGON2ID, [
                'memory_cost' => 65536,
                'time_cost' => 4,
                'threads' => 3
            ]);
            
            $result = $delegatedUserManager->updateDelegatedUser($user_id, 
                ['password_hash' => $password_hash], $current_user);
            
            if ($result['success']) {
                $result['message'] = 'Password changed successfully';
                http_response_code(200);
            } else {
                http_response_code(400);
            }
            echo json_encode($result);
            break;
            
        case 'activity_log':
            $user_id = intval($_GET['user_id'] ?? 0);
            $limit = intval($_GET['limit'] ?? 100);
            
            if (!$user_id) {
                http_response_code(400);
                echo json_encode(['success' => false, 'message' => 'User ID is required']);
                exit;
            }
            
            // Ownership is enforced inside getActivityLog: only root and the
            // parent account may view a delegated user's activity.
            $activity = $delegatedUserManager->getActivityLog($user_id, $current_user, $limit);
            if ($activity === false) {
                http_response_code(403);
                echo json_encode(['success' => false, 'message' => 'Not authorized to view this activity log']);
                exit;
            }
            echo json_encode(['success' => true, 'activity' => $activity]);
            break;
            
        case 'check_username':
            $username = $_GET['username'] ?? '';
            
            if (empty($username)) {
                http_response_code(400);
                echo json_encode(['success' => false, 'message' => 'Username is required']);
                exit;
            }
            
            // Check if username exists (basic check)
            $exists = false;
            
            // Check system users (the posix extension is not guaranteed in
            // every WHP PHP runtime — fall back to getent)
            if (function_exists('posix_getpwnam')) {
                if (posix_getpwnam($username) !== false) {
                    $exists = true;
                }
            } else {
                exec('getent passwd ' . escapeshellarg($username) . ' >/dev/null 2>&1', $getent_out, $getent_rc);
                if ($getent_rc === 0) {
                    $exists = true;
                } elseif ($getent_rc !== 2) {
                    // 2 = not found; anything else means the probe itself
                    // failed and the system-user check is degraded to DB-only
                    error_log("check_username: getent probe failed (rc $getent_rc)");
                }
            }
            
            // Check delegated users
            if (!$exists) {
                try {
                    require_once('/docker/whp/web/libs/mysqlmgmt.php');
                    $db = (new mysqlmgmt())->getMySQLConnection();
                    $stmt = $db->prepare("SELECT COUNT(*) FROM whp.delegated_users WHERE username = :username");
                    $stmt->execute([':username' => $username]);
                    $exists = $stmt->fetchColumn() > 0;
                } catch (Exception $e) {
                    error_log("Error checking username: " . $e->getMessage());
                    http_response_code(500);
                    echo json_encode(['success' => false, 'message' => 'Database error']);
                    exit;
                }
            }
            
            echo json_encode(['success' => true, 'exists' => $exists]);
            break;
            
        case 'cleanup_sessions':
            // Only root can cleanup sessions
            if ($current_user !== 'root') {
                http_response_code(403);
                echo json_encode(['success' => false, 'message' => 'Admin access required']);
                exit;
            }
            
            $cleaned = $delegatedUserManager->cleanupExpiredSessions();
            echo json_encode(['success' => true, 'cleaned_sessions' => $cleaned]);
            break;
            
        default:
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => 'Invalid action']);
            break;
    }
    
} catch (Exception $e) {
    error_log("Delegated user management API error: " . $e->getMessage());
    http_response_code(500);
    echo json_encode(['success' => false, 'message' => 'Internal server error']);
}