"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const base_monitor_1 = require("../../../src/core/base-monitor");
const errors_1 = require("../../../src/types/errors");
function createAdapterStub() {
    return {
        getPlatform: () => 'test',
        isSupported: (feature) => feature !== 'unsupported.feature',
        executeCommand: async () => ({
            stdout: '',
            stderr: '',
            exitCode: 0,
            platform: 'test',
            executionTime: 0,
            command: ''
        }),
        readFile: async () => '',
        fileExists: async () => true,
        getCPUInfo: async () => ({}),
        getCPUUsage: async () => ({ overall: 10 }),
        getCPUTemperature: async () => ([]),
        getMemoryInfo: async () => ({ total: 1, available: 1 }),
        getMemoryUsage: async () => ({}),
        getDiskInfo: async () => ({}),
        getDiskIO: async () => ({}),
        getNetworkInterfaces: async () => ({}),
        getNetworkStats: async () => ({}),
        getProcesses: async () => ({}),
        getProcessInfo: async () => ({}),
        getSystemInfo: async () => ({}),
        getSystemLoad: async () => ({ load1: 0.1, load5: 0.2, load15: 0.3 }),
        getDiskUsage: async () => ({}),
        getDiskStats: async () => ({}),
        getMounts: async () => ({}),
        getFileSystems: async () => ({}),
        getNetworkConnections: async () => ({}),
        getDefaultGateway: async () => ({}),
        getProcessList: async () => ({}),
        killProcess: async () => true,
        getProcessOpenFiles: async () => [],
        getProcessEnvironment: async () => ({}),
        getSystemUptime: async () => ({}),
        getSystemUsers: async () => ([]),
        getSystemServices: async () => ([]),
        getSupportedFeatures: () => ({
            cpu: { info: true, usage: true, temperature: true, frequency: true, cache: true, perCore: true, cores: true },
            memory: { info: true, usage: true, swap: true, pressure: true, detailed: true, virtual: true },
            disk: { info: true, io: true, health: true, smart: true, filesystem: true, usage: true, stats: true, mounts: true, filesystems: true },
            network: { interfaces: true, stats: true, connections: true, bandwidth: true, gateway: true },
            process: { list: true, details: true, tree: true, monitor: true, info: true, kill: true, openFiles: true, environment: true },
            system: { info: true, load: true, uptime: true, users: true, services: true }
        })
    };
}
class TestMonitor extends base_monitor_1.BaseMonitor {
    constructor(adapter) {
        super(adapter, { cacheTTL: 20 });
        this.callCount = 0;
    }
    getDefaultConfig() {
        return {
            cacheEnabled: true,
            cacheTTL: 10
        };
    }
    async info() {
        this.callCount += 1;
        return this.createSuccessResult({ value: this.callCount });
    }
    async cachedOperation() {
        return this.executeWithCache('test', async () => {
            this.callCount += 1;
            return { value: this.callCount };
        }, 50);
    }
    handleErrorPublic(error) {
        return this.handleError(error);
    }
    validateFeature(feature) {
        this.validatePlatformSupport(feature);
    }
}
describe('BaseMonitor', () => {
    it('executeWithCache 命中缓存时返回 cached 结果', async () => {
        const monitor = new TestMonitor(createAdapterStub());
        const first = await monitor.cachedOperation();
        const second = await monitor.cachedOperation();
        (0, chai_1.expect)(first.success).to.be.true;
        if (!first.success) {
            throw new Error('expected success');
        }
        (0, chai_1.expect)(first.cached).to.be.false;
        (0, chai_1.expect)(first.data.value).to.equal(1);
        (0, chai_1.expect)(second.success).to.be.true;
        if (!second.success) {
            throw new Error('expected success');
        }
        (0, chai_1.expect)(second.cached).to.be.true;
        (0, chai_1.expect)(second.data.value).to.equal(first.data.value);
    });
    it('withCaching(false) 会禁用缓存', async () => {
        const monitor = new TestMonitor(createAdapterStub());
        monitor.withCaching(false);
        const first = await monitor.cachedOperation();
        const second = await monitor.cachedOperation();
        (0, chai_1.expect)(first.success).to.be.true;
        if (!first.success) {
            throw new Error('expected success');
        }
        (0, chai_1.expect)(first.cached).to.be.false;
        (0, chai_1.expect)(second.success).to.be.true;
        if (!second.success) {
            throw new Error('expected success');
        }
        (0, chai_1.expect)(second.cached).to.be.false;
        (0, chai_1.expect)(second.data.value).to.equal(first.data.value + 1);
    });
    it('monitor 方法会触发回调并可取消订阅', async () => {
        const monitor = new TestMonitor(createAdapterStub());
        const values = [];
        await new Promise((resolve) => {
            const subscription = monitor.monitor(10, (data) => {
                values.push(data.value);
                subscription.unsubscribe();
                resolve();
            });
        });
        (0, chai_1.expect)(values).to.have.lengthOf(1);
        (0, chai_1.expect)(monitor.getActiveSubscriptions()).to.equal(0);
    });
    it('handleError 会将错误包装成 MonitorError', () => {
        const monitor = new TestMonitor(createAdapterStub());
        monitor.on('error', () => undefined);
        const result = monitor.handleErrorPublic(new Error('boom'));
        (0, chai_1.expect)(result.success).to.be.false;
        if (result.success) {
            throw new Error('expected failure');
        }
        (0, chai_1.expect)(result.error).to.be.instanceOf(errors_1.MonitorError);
        (0, chai_1.expect)(result.error.code).to.equal(errors_1.ErrorCode.COMMAND_FAILED);
    });
    it('validatePlatformSupport 在不支持的功能上抛出异常', () => {
        const monitor = new TestMonitor(createAdapterStub());
        (0, chai_1.expect)(() => monitor.validateFeature('unsupported.feature')).to.throw(errors_1.MonitorError);
    });
    it('destroy 会清理订阅与缓存', async () => {
        const monitor = new TestMonitor(createAdapterStub());
        await monitor.cachedOperation();
        monitor.monitor(5, () => undefined);
        (0, chai_1.expect)(monitor.getActiveSubscriptions()).to.equal(1);
        monitor.destroy();
        (0, chai_1.expect)(monitor.getActiveSubscriptions()).to.equal(0);
        (0, chai_1.expect)(monitor.getCacheStats()?.size).to.equal(0);
    });
});
describe('BaseMonitor.warnDegradation — Deno 兼容性降级警告', () => {
    let originalWarn;
    let warnCalls;
    beforeEach(() => {
        // 重置静态 Set（访问私有静态属性）
        base_monitor_1.BaseMonitor.warnedDegradations?.clear();
        originalWarn = console.warn;
        warnCalls = [];
        console.warn = (...args) => { warnCalls.push(args.join(' ')); };
    });
    afterEach(() => {
        console.warn = originalWarn;
        base_monitor_1.BaseMonitor.warnedDegradations?.clear();
    });
    it('T024: 相同 key 首次调用时应触发 console.warn', () => {
        base_monitor_1.BaseMonitor.warnDegradation('cpu.command_failed', 'PowerShell WMI 不可用');
        (0, chai_1.expect)(warnCalls).to.have.lengthOf(1);
        (0, chai_1.expect)(warnCalls[0]).to.include('[node-os-utils]');
        (0, chai_1.expect)(warnCalls[0]).to.include('cpu');
    });
    it('T024: 相同 key 第二次调用时不应重复触发 console.warn', () => {
        base_monitor_1.BaseMonitor.warnDegradation('cpu.command_failed', 'PowerShell WMI 不可用');
        base_monitor_1.BaseMonitor.warnDegradation('cpu.command_failed', 'PowerShell WMI 不可用');
        (0, chai_1.expect)(warnCalls).to.have.lengthOf(1);
    });
    it('T024: 不同 key 应各自独立触发一次 console.warn', () => {
        base_monitor_1.BaseMonitor.warnDegradation('cpu.command_failed', 'CPU 降级');
        base_monitor_1.BaseMonitor.warnDegradation('memory.command_failed', 'Memory 降级');
        (0, chai_1.expect)(warnCalls).to.have.lengthOf(2);
    });
});
//# sourceMappingURL=base-monitor.test.js.map