import * as plugins from '../../plugins.js';
import * as interfaces from '../../../dist_ts_interfaces/index.js';
import { requireOpsAuth } from '../helpers/auth.js';
export class RadiusHandler {
    opsServerRef;
    constructor(opsServerRef) {
        this.opsServerRef = opsServerRef;
        this.registerHandlers();
    }
    registerHandlers() {
        const viewRouter = this.opsServerRef.viewRouter;
        const adminRouter = this.opsServerRef.adminRouter;
        // ========================================================================
        // RADIUS Client Management
        // ========================================================================
        // Get all RADIUS clients (read)
        viewRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getRadiusClients', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return { clients: [] };
            }
            const clients = radiusServer.getClients();
            return {
                clients: clients.map(c => ({
                    name: c.name,
                    ipRange: c.ipRange,
                    description: c.description,
                    enabled: c.enabled,
                })),
            };
        }));
        // Add or update a RADIUS client (write)
        adminRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('setRadiusClient', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, {
                scope: 'radius:write',
                requireAdminIdentity: true,
            });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return { success: false, message: 'RADIUS server not configured' };
            }
            try {
                await radiusServer.addClient(dataArg.client);
                return { success: true };
            }
            catch (error) {
                return { success: false, message: error.message };
            }
        }));
        // Remove a RADIUS client (write)
        adminRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('removeRadiusClient', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, {
                scope: 'radius:write',
                requireAdminIdentity: true,
            });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return { success: false, message: 'RADIUS server not configured' };
            }
            const removed = radiusServer.removeClient(dataArg.name);
            return {
                success: removed,
                message: removed ? undefined : 'Client not found',
            };
        }));
        // ========================================================================
        // VLAN Mapping Management
        // ========================================================================
        // Get all VLAN mappings (read)
        viewRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getVlanMappings', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return {
                    mappings: [],
                    config: { defaultVlan: 1, allowUnknownMacs: true },
                };
            }
            const vlanManager = radiusServer.getVlanManager();
            const mappings = vlanManager.getAllMappings();
            const config = vlanManager.getConfig();
            return {
                mappings: mappings.map(m => ({
                    mac: m.mac,
                    vlan: m.vlan,
                    description: m.description,
                    enabled: m.enabled,
                    createdAt: m.createdAt,
                    updatedAt: m.updatedAt,
                })),
                config: {
                    defaultVlan: config.defaultVlan,
                    allowUnknownMacs: config.allowUnknownMacs,
                },
            };
        }));
        // Add or update a VLAN mapping (write)
        adminRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('setVlanMapping', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, {
                scope: 'radius:write',
                requireAdminIdentity: true,
            });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return { success: false, message: 'RADIUS server not configured' };
            }
            try {
                const vlanManager = radiusServer.getVlanManager();
                const mapping = await vlanManager.addMapping(dataArg.mapping);
                return {
                    success: true,
                    mapping: {
                        mac: mapping.mac,
                        vlan: mapping.vlan,
                        description: mapping.description,
                        enabled: mapping.enabled,
                        createdAt: mapping.createdAt,
                        updatedAt: mapping.updatedAt,
                    },
                };
            }
            catch (error) {
                return { success: false, message: error.message };
            }
        }));
        // Remove a VLAN mapping (write)
        adminRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('removeVlanMapping', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, {
                scope: 'radius:write',
                requireAdminIdentity: true,
            });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return { success: false, message: 'RADIUS server not configured' };
            }
            const vlanManager = radiusServer.getVlanManager();
            const removed = await vlanManager.removeMapping(dataArg.mac);
            return {
                success: removed,
                message: removed ? undefined : 'Mapping not found',
            };
        }));
        // Update VLAN configuration (write)
        adminRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('updateVlanConfig', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, {
                scope: 'radius:write',
                requireAdminIdentity: true,
            });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return {
                    success: false,
                    config: { defaultVlan: 1, allowUnknownMacs: true },
                };
            }
            const vlanManager = radiusServer.getVlanManager();
            vlanManager.updateConfig({
                defaultVlan: dataArg.defaultVlan,
                allowUnknownMacs: dataArg.allowUnknownMacs,
            });
            const config = vlanManager.getConfig();
            return {
                success: true,
                config: {
                    defaultVlan: config.defaultVlan,
                    allowUnknownMacs: config.allowUnknownMacs,
                },
            };
        }));
        // Test VLAN assignment (read)
        viewRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('testVlanAssignment', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return { assigned: false, vlan: 0, isDefault: false };
            }
            const vlanManager = radiusServer.getVlanManager();
            const result = vlanManager.assignVlan(dataArg.mac);
            return {
                assigned: result.assigned,
                vlan: result.vlan,
                isDefault: result.isDefault,
                matchedRule: result.matchedRule
                    ? {
                        mac: result.matchedRule.mac,
                        vlan: result.matchedRule.vlan,
                        description: result.matchedRule.description,
                    }
                    : undefined,
            };
        }));
        // ========================================================================
        // Accounting / Session Management
        // ========================================================================
        // Get active sessions (read)
        viewRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getRadiusSessions', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return { sessions: [], totalCount: 0 };
            }
            const accountingManager = radiusServer.getAccountingManager();
            let sessions = accountingManager.getActiveSessions();
            // Apply filters
            if (dataArg.filter) {
                if (dataArg.filter.username) {
                    sessions = sessions.filter(s => s.username === dataArg.filter.username);
                }
                if (dataArg.filter.nasIpAddress) {
                    sessions = sessions.filter(s => s.nasIpAddress === dataArg.filter.nasIpAddress);
                }
                if (dataArg.filter.vlanId !== undefined) {
                    sessions = sessions.filter(s => s.vlanId === dataArg.filter.vlanId);
                }
            }
            return {
                sessions: sessions.map(s => ({
                    sessionId: s.sessionId,
                    username: s.username,
                    macAddress: s.macAddress,
                    nasIpAddress: s.nasIpAddress,
                    nasIdentifier: s.nasIdentifier,
                    vlanId: s.vlanId,
                    framedIpAddress: s.framedIpAddress,
                    startTime: s.startTime,
                    lastUpdateTime: s.lastUpdateTime,
                    status: s.status,
                    inputOctets: s.inputOctets,
                    outputOctets: s.outputOctets,
                    sessionTime: s.sessionTime,
                })),
                totalCount: sessions.length,
            };
        }));
        // Disconnect a session (write)
        adminRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('disconnectRadiusSession', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, {
                scope: 'radius:write',
                requireAdminIdentity: true,
            });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return { success: false, message: 'RADIUS server not configured' };
            }
            const accountingManager = radiusServer.getAccountingManager();
            const disconnected = await accountingManager.disconnectSession(dataArg.sessionId, dataArg.reason || 'AdminReset');
            return {
                success: disconnected,
                message: disconnected ? undefined : 'Session not found',
            };
        }));
        // Get accounting summary (read)
        viewRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getRadiusAccountingSummary', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return {
                    summary: {
                        periodStart: dataArg.startTime,
                        periodEnd: dataArg.endTime,
                        totalSessions: 0,
                        activeSessions: 0,
                        totalInputBytes: 0,
                        totalOutputBytes: 0,
                        totalSessionTime: 0,
                        averageSessionDuration: 0,
                        uniqueUsers: 0,
                        sessionsByVlan: {},
                        topUsersByTraffic: [],
                    },
                };
            }
            const accountingManager = radiusServer.getAccountingManager();
            const summary = await accountingManager.getSummary(dataArg.startTime, dataArg.endTime);
            return { summary };
        }));
        // ========================================================================
        // Statistics
        // ========================================================================
        // Get RADIUS statistics (read)
        viewRouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getRadiusStatistics', async (dataArg, toolsArg) => {
            await requireOpsAuth(this.opsServerRef, dataArg, { scope: 'radius:read' });
            const radiusServer = this.opsServerRef.dcRouterRef.radiusServer;
            if (!radiusServer) {
                return {
                    stats: {
                        running: false,
                        uptime: 0,
                        authRequests: 0,
                        authAccepts: 0,
                        authRejects: 0,
                        accountingRequests: 0,
                        activeSessions: 0,
                        vlanMappings: 0,
                        clients: 0,
                    },
                    vlanStats: {
                        totalMappings: 0,
                        enabledMappings: 0,
                        exactMatches: 0,
                        ouiPatterns: 0,
                        wildcardPatterns: 0,
                    },
                    accountingStats: {
                        activeSessions: 0,
                        totalSessionsStarted: 0,
                        totalSessionsStopped: 0,
                        totalInputBytes: 0,
                        totalOutputBytes: 0,
                        interimUpdatesReceived: 0,
                    },
                };
            }
            const stats = radiusServer.getStats();
            const vlanStats = radiusServer.getVlanManager().getStats();
            const accountingStats = radiusServer.getAccountingManager().getStats();
            return {
                stats,
                vlanStats,
                accountingStats,
            };
        }));
    }
}
//# sourceMappingURL=data:application/json;base64, 