"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NetworkMonitor = void 0;
const base_monitor_1 = require("../core/base-monitor");
const types_1 = require("../types");
/**
 * 网络监控器
 *
 * 提供网络相关的监控功能，包括接口信息、流量统计、连接状态等
 */
class NetworkMonitor extends base_monitor_1.BaseMonitor {
    // private previousStats: Map<string, NetworkStats> = new Map();
    // private lastStatsTime: number = 0;
    constructor(adapter, config = {}, cache) {
        super(adapter, config, cache);
        this.networkConfig = { ...this.getDefaultConfig(), ...config };
    }
    /**
     * 获取网络接口信息（实现抽象方法）
     */
    async info() {
        return this.interfaces();
    }
    /**
     * 获取网络接口信息
     */
    async interfaces() {
        const cacheKey = 'network-interfaces';
        return this.executeWithCache(cacheKey, async () => {
            this.validatePlatformSupport('network.interfaces');
            const rawData = await this.adapter.getNetworkInterfaces();
            return this.transformNetworkInterfaces(rawData);
        }, this.networkConfig.cacheTTL || 10000);
    }
    /**
     * 获取指定接口信息
     */
    async interfaceByName(name) {
        const interfacesResult = await this.interfaces();
        if (!interfacesResult.success || !interfacesResult.data) {
            return interfacesResult;
        }
        const networkInterface = interfacesResult.data.find(iface => iface.name === name);
        return this.createSuccessResult(networkInterface || null);
    }
    /**
     * 获取网络统计信息（异步版本）
     */
    async statsAsync(options = {}) {
        if (!this.networkConfig.includeInterfaceStats) {
            return this.createErrorResult(this.createUnsupportedError('network.stats (disabled in config)'));
        }
        const cacheKey = 'network-stats';
        const fetchStats = async () => {
            this.validatePlatformSupport('network.stats');
            const rawData = await this.adapter.getNetworkStats();
            return this.transformNetworkStats(rawData);
        };
        if (options.skipCache) {
            try {
                const data = await fetchStats();
                return this.createSuccessResult(data, false);
            }
            catch (error) {
                return this.handleError(error);
            }
        }
        return this.executeWithCache(cacheKey, fetchStats, this.networkConfig.cacheTTL || 2000 // 统计信息缓存较短
        );
    }
    /**
     * 获取指定接口的统计信息
     */
    async statsByInterface(interfaceName) {
        const statsResult = await this.statsAsync();
        if (!statsResult.success || !statsResult.data) {
            return statsResult;
        }
        const stats = statsResult.data.find(stat => stat.interface === interfaceName);
        return this.createSuccessResult(stats || null);
    }
    /**
     * 获取带宽使用情况（需要两次测量）
     */
    async bandwidth() {
        if (!this.networkConfig.includeBandwidth) {
            return this.createErrorResult(this.createUnsupportedError('network.bandwidth (disabled in config)'));
        }
        const interval = this.networkConfig.bandwidthInterval || 1000;
        // 第一次测量
        const firstStatsResult = await this.statsAsync({ skipCache: true });
        if (!firstStatsResult.success || !firstStatsResult.data) {
            throw new Error('Failed to get network stats for bandwidth calculation');
        }
        // 等待指定间隔
        await new Promise(resolve => setTimeout(resolve, interval));
        // 第二次测量
        const secondStatsResult = await this.statsAsync({ skipCache: true });
        if (!secondStatsResult.success || !secondStatsResult.data) {
            throw new Error('Failed to get second network stats for bandwidth calculation');
        }
        // 计算带宽
        const bandwidth = this.calculateBandwidth(firstStatsResult.data, secondStatsResult.data, interval);
        return this.createSuccessResult({
            interval,
            interfaces: bandwidth
        });
    }
    /**
     * 获取活跃的网络连接
     */
    async connections() {
        if (!this.networkConfig.includeConnections) {
            return this.createErrorResult(this.createUnsupportedError('network.connections (disabled in config)'));
        }
        const cacheKey = 'network-connections';
        return this.executeWithCache(cacheKey, async () => {
            this.validatePlatformSupport('network.connections');
            const rawData = await this.adapter.getNetworkConnections();
            return this.transformNetworkConnections(rawData);
        }, this.networkConfig.cacheTTL || 5000);
    }
    /**
     * 获取默认网关信息
     */
    async gateway() {
        const cacheKey = 'network-gateway';
        return this.executeWithCache(cacheKey, async () => {
            this.validatePlatformSupport('network.gateway');
            const rawData = await this.adapter.getDefaultGateway();
            return this.transformGatewayInfo(rawData);
        }, this.networkConfig.cacheTTL || 30000);
    }
    /**
     * 获取公网 IP 地址
     */
    async publicIP() {
        const cacheKey = 'network-public-ip';
        return this.executeWithCache(cacheKey, async () => {
            // 这个功能可能需要外部服务，暂时返回空结果
            return {
                ipv4: undefined,
                ipv6: undefined
            };
        }, this.networkConfig.cacheTTL || 300000 // 公网 IP 缓存 5 分钟
        );
    }
    /**
     * 网络健康检查
     */
    async healthCheck() {
        const cacheKey = 'network-health';
        return this.executeWithCache(cacheKey, async () => {
            const issues = [];
            const checks = {
                interfaceStatus: true,
                connectivity: true,
                performance: true
            };
            // 检查网络接口状态
            try {
                const interfacesResult = await this.interfaces();
                if (interfacesResult.success && interfacesResult.data) {
                    const activeInterfaces = interfacesResult.data.filter(iface => iface.state === 'up' && !iface.internal);
                    if (activeInterfaces.length === 0) {
                        issues.push('No active network interfaces found');
                        checks.interfaceStatus = false;
                    }
                    // 检查是否有错误率高的接口
                    if (this.networkConfig.includeInterfaceStats) {
                        const statsResult = await this.statsAsync();
                        if (statsResult.success && statsResult.data) {
                            for (const stats of statsResult.data) {
                                const totalPackets = stats.rxPackets + stats.txPackets;
                                const totalErrors = stats.rxErrors + stats.txErrors;
                                const errorRate = totalPackets > 0 ? (totalErrors / totalPackets) * 100 : 0;
                                if (errorRate > 5) {
                                    issues.push(`High error rate on interface ${stats.interface}: ${errorRate.toFixed(2)}%`);
                                    checks.performance = false;
                                }
                            }
                        }
                    }
                }
            }
            catch (error) {
                issues.push('Failed to check network interface status');
                checks.interfaceStatus = false;
            }
            // 检查默认网关连通性
            try {
                const gatewayResult = await this.gateway();
                if (!gatewayResult.success || !gatewayResult.data) {
                    issues.push('No default gateway configured');
                    checks.connectivity = false;
                }
            }
            catch (error) {
                issues.push('Failed to get gateway information');
                checks.connectivity = false;
            }
            // 确定整体健康状态
            let status = 'healthy';
            if (!checks.interfaceStatus || !checks.connectivity) {
                status = 'critical';
            }
            else if (!checks.performance || issues.length > 0) {
                status = 'warning';
            }
            return {
                status,
                issues,
                checks
            };
        }, this.networkConfig.cacheTTL || 30000);
    }
    /**
     * 获取网络总览信息
     */
    async overview() {
        const cacheKey = 'network-overview';
        return this.executeWithCache(cacheKey, async () => {
            const [interfacesResult, statsResult] = await Promise.all([
                this.interfaces(),
                this.statsAsync().catch(() => ({ success: false, data: null }))
            ]);
            if (!interfacesResult.success || !interfacesResult.data) {
                throw new Error('Failed to get network interfaces');
            }
            const interfaces = interfacesResult.data;
            const activeInterfaces = interfaces.filter(iface => iface.state === 'up' && !iface.internal).length;
            let totalRxBytes = 0;
            let totalTxBytes = 0;
            let totalPackets = 0;
            let totalErrors = 0;
            if (statsResult.success && statsResult.data) {
                for (const stats of statsResult.data) {
                    totalRxBytes += stats.rxBytes.toBytes();
                    totalTxBytes += stats.txBytes.toBytes();
                    totalPackets += stats.rxPackets + stats.txPackets;
                    totalErrors += stats.rxErrors + stats.txErrors;
                }
            }
            return {
                interfaces: interfaces.length,
                activeInterfaces,
                totalRxBytes: new types_1.DataSize(totalRxBytes),
                totalTxBytes: new types_1.DataSize(totalTxBytes),
                totalPackets,
                totalErrors
            };
        }, this.networkConfig.cacheTTL || 10000);
    }
    /**
     * 配置是否包含接口统计
     */
    withInterfaceStats(include) {
        this.networkConfig.includeInterfaceStats = include;
        return this;
    }
    /**
     * 配置是否包含连接信息
     */
    withConnections(include) {
        this.networkConfig.includeConnections = include;
        return this;
    }
    /**
     * 配置是否包含带宽监控
     */
    withBandwidth(include) {
        this.networkConfig.includeBandwidth = include;
        return this;
    }
    /**
     * 配置目标网络接口
     */
    withInterfaces(interfaces) {
        this.networkConfig.interfaces = interfaces;
        return this;
    }
    /**
     * 配置带宽监控间隔
     */
    withBandwidthInterval(interval) {
        this.networkConfig.bandwidthInterval = interval;
        return this;
    }
    /**
     * 获取默认配置
     */
    getDefaultConfig() {
        return {
            interval: 2000,
            timeout: 10000,
            cacheEnabled: true,
            cacheTTL: 5000,
            samples: 1,
            includeDetails: true,
            includeInterfaceStats: true,
            includeConnections: false, // 连接信息可能较多，默认不包含
            includeBandwidth: false, // 带宽监控需要额外计算，默认不包含
            bandwidthInterval: 1000,
            unit: 'auto'
        };
    }
    // 私有转换方法
    /**
     * 转换网络接口信息
     */
    /**
     * 将平台适配器返回的原始接口数据统一转换为 NetworkInterface 结构
     * 支持 Node.js os.networkInterfaces() 返回的对象以及适配器自定义的数组格式
     */
    transformNetworkInterfaces(rawData) {
        if (!rawData) {
            return [];
        }
        /**
         * 收集单个网卡的信息并写入结果数组
         */
        const addInterface = (name, addresses, raw) => {
            if (!Array.isArray(addresses) || addresses.length === 0) {
                return;
            }
            const transformedAddresses = addresses.map((addr) => ({
                address: addr.address || '',
                netmask: addr.netmask || '',
                family: addr.family === 'IPv6' || addr.family === 6 ? 'IPv6' : 'IPv4',
                internal: addr.internal || false,
                scopeid: addr.scopeid
            }));
            const firstAddr = addresses[0];
            const rawState = raw?.state ?? raw?.operstate ?? raw?.status;
            const networkInterface = {
                name,
                addresses: transformedAddresses,
                mac: firstAddr?.mac || '',
                state: this.normalizeInterfaceState(rawState, firstAddr),
                type: this.inferInterfaceType(name),
                mtu: firstAddr?.mtu || 1500,
                internal: Boolean(raw?.internal ?? firstAddr?.internal ?? false),
                speed: firstAddr?.speed,
                duplex: firstAddr?.duplex
            };
            if (this.shouldIncludeInterface(networkInterface)) {
                interfaces.push(networkInterface);
            }
        };
        const interfaces = [];
        if (Array.isArray(rawData)) {
            for (const item of rawData) {
                if (!item || typeof item !== 'object')
                    continue;
                const name = item.name || item.interface;
                if (!name)
                    continue;
                const addresses = Array.isArray(item.addresses)
                    ? item.addresses
                    : [{
                            address: item.address,
                            netmask: item.netmask,
                            family: item.family,
                            internal: item.internal,
                            mac: item.mac,
                            mtu: item.mtu,
                            scopeid: item.scopeid
                        }];
                addInterface(name, addresses, item);
            }
            return interfaces;
        }
        if (typeof rawData === 'object') {
            for (const [name, addresses] of Object.entries(rawData)) {
                addInterface(name, addresses, rawData[name]);
            }
        }
        return interfaces;
    }
    /**
     * 转换网络统计信息
     */
    transformNetworkStats(rawData) {
        if (!Array.isArray(rawData)) {
            return [];
        }
        return rawData
            .filter(stats => this.shouldIncludeInterface({ name: stats.interface }))
            .map(stats => ({
            interface: stats.interface || stats.name || 'unknown',
            rxBytes: new types_1.DataSize(this.safeParseNumber(stats.rxBytes || stats.rx_bytes)),
            txBytes: new types_1.DataSize(this.safeParseNumber(stats.txBytes || stats.tx_bytes)),
            rxPackets: this.safeParseNumber(stats.rxPackets || stats.rx_packets),
            txPackets: this.safeParseNumber(stats.txPackets || stats.tx_packets),
            rxErrors: this.safeParseNumber(stats.rxErrors || stats.rx_errors),
            txErrors: this.safeParseNumber(stats.txErrors || stats.tx_errors),
            rxDropped: this.safeParseNumber(stats.rxDropped || stats.rx_dropped),
            txDropped: this.safeParseNumber(stats.txDropped || stats.tx_dropped),
            rxSpeed: stats.rxSpeed,
            txSpeed: stats.txSpeed
        }));
    }
    /**
     * 转换网络连接信息
     */
    transformNetworkConnections(rawData) {
        if (!Array.isArray(rawData)) {
            return [];
        }
        return rawData.map(conn => ({
            protocol: conn.protocol || 'unknown',
            localAddress: conn.localAddress || conn.local_address,
            localPort: conn.localPort || conn.local_port,
            remoteAddress: conn.remoteAddress || conn.remote_address,
            remotePort: conn.remotePort || conn.remote_port,
            state: conn.state || 'unknown',
            pid: conn.pid
        }));
    }
    /**
     * 转换网关信息
     */
    transformGatewayInfo(rawData) {
        // 网关信息在 Linux 点对点链路中可能只有接口（例如 `default dev ppp0`），此时仍视为有效路由
        if (!rawData || (rawData.gateway == null && rawData.interface == null && rawData.iface == null && rawData.device == null)) {
            return null;
        }
        return {
            // 优先使用显式网关地址，若缺失则回退到 `address` 字段，保持与适配器输出一致
            gateway: rawData.gateway ?? rawData.address ?? null,
            // 兼容不同平台字段命名（interface/iface/device），确保能准确识别默认出口
            interface: rawData.interface || rawData.iface || rawData.device || 'unknown'
        };
    }
    /**
     * 计算带宽
     */
    calculateBandwidth(firstStats, secondStats, intervalMs) {
        const results = [];
        for (const firstStat of firstStats) {
            const secondStat = secondStats.find(s => s.interface === firstStat.interface);
            if (!secondStat)
                continue;
            const intervalSec = intervalMs / 1000;
            const rxDiff = secondStat.rxBytes.toBytes() - firstStat.rxBytes.toBytes();
            const txDiff = secondStat.txBytes.toBytes() - firstStat.txBytes.toBytes();
            const rxSpeed = Math.max(0, rxDiff / intervalSec); // 字节/秒
            const txSpeed = Math.max(0, txDiff / intervalSec); // 字节/秒
            results.push({
                interface: firstStat.interface,
                rxSpeed,
                txSpeed,
                rxSpeedFormatted: new types_1.DataSize(rxSpeed).toString(this.networkConfig.unit || 'auto') + '/s',
                txSpeedFormatted: new types_1.DataSize(txSpeed).toString(this.networkConfig.unit || 'auto') + '/s'
            });
        }
        return results;
    }
    /**
     * 推断接口状态
     */
    inferInterfaceState(addr) {
        // 如果有地址且不是内部接口，通常表示接口是活跃的
        if (addr && addr.address && !addr.internal) {
            return 'up';
        }
        // 内部接口（如回环）通常也是活跃的
        if (addr && addr.internal && addr.address) {
            return 'up';
        }
        return 'unknown';
    }
    /**
     * 推断接口类型
     */
    inferInterfaceType(name) {
        const lowerName = name.toLowerCase();
        if (lowerName.includes('lo') || lowerName.includes('loopback')) {
            return 'loopback';
        }
        if (lowerName.includes('wifi') || lowerName.includes('wlan') || lowerName.includes('wireless')) {
            return 'wifi';
        }
        if (lowerName.includes('eth') || lowerName.includes('en')) {
            return 'ethernet';
        }
        if (lowerName.includes('virt') || lowerName.includes('docker') || lowerName.includes('br-')) {
            return 'virtual';
        }
        return 'other';
    }
    /**
     * 判断是否应该包含该接口
     */
    shouldIncludeInterface(networkInterface) {
        // 如果配置了特定接口列表，只包含这些接口
        if (this.networkConfig.interfaces && this.networkConfig.interfaces.length > 0) {
            return this.networkConfig.interfaces.includes(networkInterface.name);
        }
        return true;
    }
    normalizeInterfaceState(rawState, addr) {
        // 直接复用适配器给出的状态，若不存在则回退到地址推断以保留兼容性
        if (typeof rawState === 'string') {
            const normalized = rawState.toLowerCase();
            if (/(up|running|active|online)/.test(normalized)) {
                return 'up';
            }
            if (/(down|inactive|disabled|offline)/.test(normalized)) {
                return 'down';
            }
        }
        return this.inferInterfaceState(addr);
    }
    /**
     * 安全解析数字
     */
    safeParseNumber(value) {
        if (typeof value === 'number') {
            return isNaN(value) ? 0 : value;
        }
        if (typeof value === 'string') {
            const parsed = parseFloat(value);
            return isNaN(parsed) ? 0 : parsed;
        }
        return 0;
    }
    // ==================== 向后兼容的同步方法 ====================
    /**
     * 获取网络流量统计（同步版本，向后兼容）
     * @param interval 监控间隔（毫秒）
     * @returns 网络流量统计对象或 'not supported'
     */
    inOut(interval = 1000) {
        try {
            // 对于同步版本，无法进行实际的网络监控
            // 返回基本结构，实际值需要通过异步方法获取
            return {
                total: {
                    inputMb: 0,
                    outputMb: 0
                },
                inputMb: 0,
                outputMb: 0
            };
        }
        catch (error) {
            return 'not supported';
        }
    }
    /**
     * 获取网络统计信息（同步版本，向后兼容）
     * @returns 网络统计信息数组或 'not supported'
     */
    stats() {
        try {
            // 对于同步版本，返回基本的网络接口信息
            const os = require('os');
            const interfaces = os.networkInterfaces();
            const result = [];
            for (const [name, addresses] of Object.entries(interfaces)) {
                if (Array.isArray(addresses) && addresses.length > 0) {
                    const addr = addresses[0];
                    result.push({
                        iface: name,
                        operstate: addr.internal ? 'down' : 'up',
                        rx_bytes: 0,
                        rx_dropped: 0,
                        rx_errors: 0,
                        tx_bytes: 0,
                        tx_dropped: 0,
                        tx_errors: 0,
                        internal: addr.internal,
                        address: addr.address
                    });
                }
            }
            return result;
        }
        catch (error) {
            return 'not supported';
        }
    }
}
exports.NetworkMonitor = NetworkMonitor;
//# sourceMappingURL=network-monitor.js.map