const { exec } = require('child_process');
const path = require('path');
const os = require('os');

const startMavenServer = (holoFan, emit) => {
    return new Promise((resolve, reject) => {
        freePort(holoFan.port, emit).then(() => {
            // emit('data', `Порт ${holoFan.port} теперь свободен`);
            const serverProcess = exec('mvn spring-boot:run', { cwd: holoFan.wsServerPath });

            serverProcess.stdout.on('data', (data) => {
                // console.log(data);
                if (data.toString().includes('Started')) {
                    resolve();
                    emit('connected', `Сервер Maven запущен на порту ${holoFan.port}`);
                }
            });

            serverProcess.stderr.on('data', (data) => {
                emit('data', data.toString());
            });

            serverProcess.on('error', (error) => {
                emit('error', `Ошибка запуска сервера Maven: ${error}`);
                reject(error);
            });

            serverProcess.on('close', (code) => {
                if (code !== 0) {
                    emit('disconnected', `Серверный процесс завершился с кодом ${code}`);
                    reject(new Error(`Server process exited with code ${code}`));
                }
            });
        }).catch((error) => {
            emit('error', `Ошибка освобождения порта ${holoFan.port}: ${error}`);
            reject(error);
        });
    });
};

const retryStartServer = (holoFan, emit) => {
    setTimeout(() => {
        startMavenServer(holoFan, emit).catch(console.error);
    }, 15000); // Повторная попытка через 15 секунд
};

const freePort = (port, emit) => {
    return new Promise((resolve, reject) => {
        if (os.platform() === 'win32') {
            exec(`netstat -ano | findstr :${port}`, (err, stdout, stderr) => {
                if (err || !stdout.trim()) {
                    if (stderr) emit('error', `Ошибка выполнения netstat: ${stderr}`);
                    return resolve(); // Нет процессов на этом порту
                }

                const lines = stdout.trim().split('\n');
                const pids = new Set();

                lines.forEach((line) => {
                    const parts = line.trim().split(/\s+/);
                    const pid = parts[parts.length - 1];
                    if (pid && pid !== '0') {
                        pids.add(pid);
                    }
                });

                if (pids.size === 0) return resolve(); // Нет процессов на этом порту

                let promises = [];
                pids.forEach((pid) => {
                    promises.push(new Promise((res, rej) => {
                        exec(`taskkill /PID ${pid} /F`, (err, stdout, stderr) => {
                            if (err) {
                                emit('error', `Ошибка завершения процесса ${pid}: ${stderr}`);
                                return rej(new Error(`Ошибка завершения процесса ${pid}: ${stderr}`));
                            }
                            res();
                        });
                    }));
                });

                Promise.all(promises)
                    .then(() => resolve())
                    .catch((err) => reject(err));
            });
        } else {
            exec(`lsof -i tcp:${port}`, (err, stdout, stderr) => {
                if (err || !stdout.trim()) {
                    if (stderr) emit('error', `Ошибка выполнения lsof: ${stderr}`);
                    return resolve(); // Нет процессов на этом порту
                }

                exec(`fuser -k ${port}/tcp`, (err, stdout, stderr) => {
                    if (err) {
                        emit('error', `Ошибка выполнения fuser: ${stderr}`);
                        return reject(new Error(`Ошибка выполнения fuser: ${stderr}`));
                    }
                    resolve();
                });
            });
        }
    });
};

module.exports = { startMavenServer };