import { Client } from 'ssh2';
export class VpnService {
    host;
    password;
    constructor() {
        this.host = '10.0.1.150'; // VPN Server IP
        this.password = '02!Aug2013'; // Root password
    }
    /**
     * Automatically generates an OpenVPN client config on the VPN server
     * and allocates the static VPN IP in the OpenVPN ccd directory.
     */
    async generateDeviceVpnConfig(macAddress, vpnIp) {
        return new Promise((resolve, reject) => {
            const conn = new Client();
            // Clean up the MAC address to use as a client name (remove colons)
            const clientName = `device_${macAddress.replace(/:/g, '')}`;
            // The shell script to run on the VPN Server (10.0.1.150)
            const setupScript = `
        #!/bin/bash
        cd /etc/openvpn/server
        
        # 1. Create client certificate if it doesn't exist
        if [ ! -f "easy-rsa/pki/issued/\${clientName}.crt" ]; then
          cd easy-rsa
          ./easyrsa build-client-full "\${clientName}" nopass
          cd ..
        fi

        # 2. Assign static IP in ccd (Client Config Directory)
        mkdir -p ccd
        echo "ifconfig-push \${vpnIp} 255.255.255.0" > "ccd/\${clientName}"

        # 3. Generate client .ovpn file
        cat <<EOF > "/root/\${clientName}.ovpn"
client
dev tun
proto tcp
remote 10.0.1.150 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert \${clientName}.crt
key \${clientName}.key
remote-cert-tls server
cipher AES-256-CBC
verb 3
EOF
        
        echo "SUCCESS: VPN Config generated for \${clientName} with IP \${vpnIp}"
      `;
            conn.on('ready', () => {
                conn.exec(setupScript, (err, stream) => {
                    if (err) {
                        conn.end();
                        return reject(err);
                    }
                    let output = '';
                    stream.on('close', (code, signal) => {
                        conn.end();
                        if (code === 0) {
                            resolve(true);
                        }
                        else {
                            reject(new Error(`VPN Script failed with code ${code}. Output: ${output}`));
                        }
                    }).on('data', (data) => {
                        output += data.toString();
                        console.log('STDOUT: ' + data);
                    }).stderr.on('data', (data) => {
                        output += data.toString();
                        console.error('STDERR: ' + data);
                    });
                });
            }).on('error', (err) => {
                reject(err);
            }).connect({
                host: this.host,
                port: 22,
                username: 'root',
                password: this.password,
                readyTimeout: 10000
            });
        });
    }
}
