<?php declare(strict_types=1);
/**
 * @package messenger
 * @author kputyr
 * @date 21.04.2026
 * 
 * This script authenticates connection to nchan locations
 */

use IMATHUZH\Messenger\Nchan\NchanRequest;

require_once 'common.php';

try {
    $authorized = false;    // Required for a notice to the controller
    $request = NchanRequest::fromServerRequest();

    # Check the existence of token and channel data
    $tokenId = $_SERVER['HTTP_AUTHORIZATION'] ?? reject('Authorization header missing');
    $group = $request->getChannelGroup() ?: reject('Channel group missing');

    # Read the token and authorize the access to the channel based on the requester's type
    $token = loadTokenStorage()->loadToken($tokenId);
    switch ($request->getRequesterType()) {
        case 'publisher':
            $token->authorizesPublisher(
                $request->getChannelGroup(),
                $request->getPubChannels()
            ) or reject('Unauthorized publisher: allowed channels are ' . implode(",", $token->getPubChannels($group) ?? ['null']));
            break;
        case 'listener':
            $token->authorizesPublisher(
                $request->getChannelGroup(),
                $request->getPubChannels()
            ) or reject('Unauthorized publisher: allowed are ' . implode(",", $token->getPubChannels($group) ?? ['null']));
            $token->authorizesListener(
                $request->getChannelGroup(),
                $request->getSubChannels()
            ) or reject('Unauthorized subscriber: allowed are ' . implode(",", $token->getSubChannels($group) ?? ['null']));
            break;
        case 'controller':
            $token->authorizesController(
                $request->getChannelGroup(),
                $request->getSubChannels()
            ) or reject('Unauthorized controller: allowed are ' . implode(",", $token->getCtlChannels($group) ?? ['null']));
            break;
        default:
            reject('Unknown requester type: ' . $request->getRequesterType());
    }
    # Access allowed
    $request->authorize();
    $authorized = true;
} catch (\Exception $e) {
    $request->close(403, "Access denied");
    $error = $e->getMessage();
}

$payload = $request->getRequestMetaData();
$payload['authorized'] = $authorized;
if (isset($error)) $payload['error'] = $error;

$request->notifyController('auth', $payload);
