"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProcessCollector = void 0;
const si = __importStar(require("systeminformation"));
const child_process_1 = require("child_process");
const logger_1 = require("../logger");
// Application categories for productivity classification
const CATEGORY_MAP = {
    // Browsers
    'chrome': 'browser', 'firefox': 'browser', 'msedge': 'browser', 'edge': 'browser',
    'safari': 'browser', 'opera': 'browser', 'brave': 'browser', 'vivaldi': 'browser',
    // Development
    'code': 'development', 'visual studio': 'development', 'idea': 'development',
    'webstorm': 'development', 'pycharm': 'development', 'sublime': 'development',
    'atom': 'development', 'notepad++': 'development', 'vim': 'development',
    'git': 'development', 'node': 'development', 'python': 'development',
    'java': 'development', 'docker': 'development', 'terminal': 'development',
    'powershell': 'development', 'cmd': 'development', 'bash': 'development',
    'wt': 'development', 'windowsterminal': 'development',
    // Communication
    'teams': 'communication', 'slack': 'communication', 'zoom': 'communication',
    'discord': 'communication', 'skype': 'communication', 'outlook': 'communication',
    'thunderbird': 'communication', 'telegram': 'communication',
    // Office
    'winword': 'office', 'excel': 'office', 'powerpnt': 'office',
    'onenote': 'office', 'libreoffice': 'office', 'word': 'office',
    // Design
    'figma': 'design', 'sketch': 'design', 'photoshop': 'design',
    'illustrator': 'design', 'gimp': 'design', 'inkscape': 'design',
    // Media
    'spotify': 'media', 'vlc': 'media', 'itunes': 'media',
    'netflix': 'media', 'youtube': 'media',
    // System
    'explorer': 'system', 'finder': 'system', 'svchost': 'system',
    'systemd': 'system', 'init': 'system', 'csrss': 'system',
    'dwm': 'system', 'conhost': 'system', 'winlogon': 'system',
    'lsass': 'system', 'services': 'system', 'taskmgr': 'system',
    'registry': 'system', 'rundll32': 'system',
};
function categorizeProcess(name, path) {
    const lowerName = name.toLowerCase().replace('.exe', '');
    for (const [key, category] of Object.entries(CATEGORY_MAP)) {
        if (lowerName.includes(key))
            return category;
    }
    return 'other';
}
class ProcessCollector {
    constructor() {
        this.collecting = false;
        this.lastSnapshot = [];
    }
    async collect() {
        if (this.collecting)
            return this.lastSnapshot;
        this.collecting = true;
        try {
            const processes = await si.processes();
            const list = processes.list
                .filter(p => p.pid > 0 && p.name)
                .map(p => ({
                pid: p.pid,
                name: p.name,
                cpu: p.cpu || 0,
                memory: p.mem || 0,
                memoryRss: p.memRss || 0,
                username: p.user || '',
                command: p.command || '',
                path: p.path || '',
                started: p.started || '',
                state: p.state || 'unknown',
                category: categorizeProcess(p.name, p.path || ''),
            }))
                .sort((a, b) => b.cpu - a.cpu);
            this.lastSnapshot = list;
            return list;
        }
        catch (e) {
            logger_1.logger.error('Process collection error:', e);
            return this.lastSnapshot;
        }
        finally {
            this.collecting = false;
        }
    }
    async terminate(pid, signal = 'SIGTERM') {
        try {
            const safePid = Number(pid);
            if (!Number.isFinite(safePid) || safePid <= 0) {
                logger_1.logger.error(`Invalid PID for termination: ${pid}`);
                return false;
            }
            if (process.platform === 'win32') {
                return new Promise((resolve) => {
                    const attempts = signal === 'SIGKILL'
                        ? [`taskkill /F /T /PID ${safePid}`]
                        : [`taskkill /T /PID ${safePid}`, `taskkill /F /T /PID ${safePid}`];
                    const tryTerminate = (index) => {
                        (0, child_process_1.exec)(attempts[index], (err) => {
                            if (!err) {
                                logger_1.logger.info(`Terminated PID ${safePid} using "${attempts[index]}"`);
                                resolve(true);
                                return;
                            }
                            if (index < attempts.length - 1) {
                                logger_1.logger.warn(`Terminate attempt failed for PID ${safePid}, retrying with force`, { error: err.message });
                                tryTerminate(index + 1);
                                return;
                            }
                            logger_1.logger.error(`Failed to terminate PID ${safePid}:`, err);
                            resolve(false);
                        });
                    };
                    tryTerminate(0);
                });
            }
            else {
                const sigNum = signal === 'SIGKILL' ? 9 : 15;
                process.kill(safePid, sigNum);
                logger_1.logger.info(`Sent ${signal} to PID ${safePid}`);
                return true;
            }
        }
        catch (e) {
            logger_1.logger.error(`Failed to terminate PID ${pid}:`, e);
            return false;
        }
    }
    getLastSnapshot() {
        return this.lastSnapshot;
    }
}
exports.ProcessCollector = ProcessCollector;
//# sourceMappingURL=process.js.map