"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var WebsocketRepository_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebsocketRepository = exports.serverEvents = void 0;
const common_1 = require("@nestjs/common");
const websockets_1 = require("@nestjs/websockets");
const socket_io_1 = require("socket.io");
const event_repository_1 = require("./event.repository");
const logging_repository_1 = require("./logging.repository");
const misc_1 = require("../utils/misc");
exports.serverEvents = [
    'ConfigUpdate',
    'AppRestart',
    'HlsSegmentRequest',
    'HlsSegmentResult',
    'HlsHeartbeat',
    'HlsSessionRequest',
    'HlsSessionResult',
    'HlsSessionEnd',
];
let WebsocketRepository = WebsocketRepository_1 = class WebsocketRepository {
    eventRepository;
    logger;
    authFn;
    server;
    constructor(eventRepository, logger) {
        this.eventRepository = eventRepository;
        this.logger = logger;
        this.logger.setContext(WebsocketRepository_1.name);
    }
    afterInit(server) {
        this.logger.log('Initialized websocket server');
        for (const event of exports.serverEvents) {
            server.on(event, (...args) => {
                this.logger.debug(`Server event: ${event} (receive)`);
                (0, misc_1.handlePromiseError)(this.eventRepository.onEvent({ name: event, args, server: true }), this.logger);
            });
        }
    }
    async handleConnection(client) {
        try {
            this.logger.log(`Websocket Connect:    ${client.id}`);
            const auth = await this.authenticate(client);
            await client.join(auth.user.id);
            if (auth.session) {
                await client.join(auth.session.id);
            }
            await this.eventRepository.emit('WebsocketConnect', { userId: auth.user.id });
        }
        catch (error) {
            this.logger.error(`Websocket connection error: ${error}`, error?.stack);
            client.emit('error', 'unauthorized');
            client.disconnect();
        }
    }
    async handleDisconnect(client) {
        this.logger.log(`Websocket Disconnect: ${client.id}`);
        await client.leave(client.nsp.name);
    }
    clientSend(event, room, ...data) {
        this.server?.to(room).emit(event, ...data);
    }
    clientBroadcast(event, ...data) {
        this.server?.emit(event, ...data);
    }
    serverSend(event, ...args) {
        this.logger.debug(`Server event: ${event} (send)`);
        this.server?.serverSideEmit(event, ...args);
    }
    setAuthFn(fn) {
        this.authFn = fn;
    }
    async authenticate(client) {
        if (!this.authFn) {
            throw new Error('Auth function not set');
        }
        return this.authFn(client);
    }
};
exports.WebsocketRepository = WebsocketRepository;
__decorate([
    (0, websockets_1.WebSocketServer)(),
    __metadata("design:type", socket_io_1.Server)
], WebsocketRepository.prototype, "server", void 0);
exports.WebsocketRepository = WebsocketRepository = WebsocketRepository_1 = __decorate([
    (0, websockets_1.WebSocketGateway)({
        cors: true,
        path: '/api/socket.io',
        transports: ['websocket'],
    }),
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [event_repository_1.EventRepository,
        logging_repository_1.LoggingRepository])
], WebsocketRepository);
//# sourceMappingURL=websocket.repository.js.map