<?php
/**
 * JaaS JWT Helper
 * Generates signed JWT tokens for Jitsi as a Service (8x8 JaaS)
 * Uses RS256 (RSA + SHA-256) signing with the provided private key.
 *
 * IMPORTANT: You must set JAAS_API_KEY_ID in config/jaas.php.
 * Find it in your JaaS Dashboard → API Keys. Format: vpaas-magic-cookie-xxx/YOUR-KEY-ID
 */
class JaasHelper {

    /**
     * Generate a signed JaaS JWT for the given user and room.
     *
     * @param array  $user        User data ['id', 'name', 'email', 'avatar']
     * @param string $roomName    The Jitsi room name (without app ID prefix)
     * @param bool   $isModerator Whether the user should be a moderator (mentor/admin)
     * @param int    $ttl         Token validity in seconds (default 2 hours)
     */
    public static function generateToken(array $user, string $roomName, bool $isModerator = false, int $ttl = 7200): string {
        $appId      = JAAS_APP_ID;
        $privateKey = JAAS_PRIVATE_KEY;
        $apiKeyId   = defined('JAAS_API_KEY_ID') ? JAAS_API_KEY_ID : '';

        $now = time();

        // --- Header ---
        $header = self::base64urlEncode(json_encode([
            'alg' => 'RS256',
            'kid' => $apiKeyId,
            'typ' => 'JWT',
        ]));

        // --- Payload ---
        $payload = self::base64urlEncode(json_encode([
            'iss'     => 'chat',
            'aud'     => 'jitsi',
            'iat'     => $now,
            'nbf'     => $now,
            'exp'     => $now + $ttl,
            'sub'     => $appId,
            'room'    => $roomName,
            'context' => [
                'user' => [
                    'id'           => (string)$user['id'],
                    'name'         => $user['name'],
                    'email'        => $user['email'],
                    'avatar'       => $user['avatar'] ?? '',
                    'moderator'    => $isModerator ? 'true' : 'false',
                ],
                'features' => [
                    'livestreaming' => 'false',
                    'recording'     => 'false',
                    'transcription' => 'false',
                    'outbound-call' => 'false',
                ],
            ],
        ]));

        // --- Signature ---
        $signingInput = $header . '.' . $payload;
        $privateKeyResource = openssl_pkey_get_private($privateKey);
        if ($privateKeyResource === false) {
            throw new RuntimeException('JaaS: Failed to load private key.');
        }

        $signature = '';
        openssl_sign($signingInput, $signature, $privateKeyResource, OPENSSL_ALGO_SHA256);

        return $signingInput . '.' . self::base64urlEncode($signature);
    }

    /**
     * URL-safe base64 encode (no padding, +/ → -_)
     */
    private static function base64urlEncode(string $data): string {
        return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
    }

    /**
     * Build the full Jitsi room name for a session ID.
     * Format: BOAFO-Session-{id}  (unique per session)
     */
    public static function roomName(int $sessionId): string {
        return 'BOAFOSession' . $sessionId;
    }
}
