const { Client } = require('ssh2');
const fs = require('fs');
require('dotenv').config();

const getSSHConfig = () => {
    const config = {
        host: process.env.SSH_HOST,
        username: process.env.SSH_USER,
        port: 22,
    };

    let privateKeyPath = process.env.SSH_KEY_PATH;
    if (privateKeyPath && privateKeyPath.endsWith('.pub')) {
        privateKeyPath = privateKeyPath.replace('.pub', '');
    }

    if (privateKeyPath) {
        config.privateKey = fs.readFileSync(privateKeyPath);
    } else if (process.env.SSH_PASSWORD) {
        config.password = process.env.SSH_PASSWORD;
    }

    return config;
};

const execCommand = (command) => {
    return new Promise((resolve, reject) => {
        const conn = new Client();
        conn.on('ready', () => {
            conn.exec(command, (err, stream) => {
                if (err) {
                    conn.end();
                    return reject(err);
                }
                let output = '';
                let errorOutput = '';
                stream.on('close', (code, signal) => {
                    conn.end();
                    if (code !== 0) return reject(new Error(`Command failed with code ${code}: ${errorOutput}`));
                    resolve(output.trim());
                }).on('data', (data) => {
                    output += data;
                }).stderr.on('data', (data) => {
                    errorOutput += data;
                });
            });
        }).on('error', (err) => {
            reject(err);
        }).connect(getSSHConfig());
    });
};

const readFile = (filePath) => {
    return execCommand(`cat "${filePath}"`);
};

const writeFile = (filePath, content) => {
    // Basic implementation: echo content to file.
    // WARNING: Not safe for large files or complex headers, but start simple.
    // Ideally use SFTP for robustness later.
    const escapedContent = content.replace(/"/g, '\\"');
    return execCommand(`echo "${escapedContent}" > "${filePath}"`);
};

module.exports = { execCommand, readFile, writeFile };
