#!/usr/bin/env node
/**
 * ===============================================================================
 *                    MATTERMOST LOCAL API FOR BTCPAY SSH COMMANDS
 * ===============================================================================
 * Created: September 10, 2025
 * Purpose: Local web API that runs SSH commands to retrieve BTCPay onion addresses
 * Deploy: On your Mattermost server (not the VPS)
 * Usage: Mattermost slash commands → Local API → SSH to VPS → Return data
 */

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

const app = express();
const PORT = process.env.PORT || 3333;

// Configuration - ADJUST THESE PATHS FOR YOUR MATTERMOST SERVER
const config = {
    vps_domain: 'thebankofdebbie.giize.com',
    vps_port: 2255,
    vps_user: 'sysadmin',
    ssh_key_path: '/mnt/c/Production/Source/LittleShop/Hostinger/vps_hardening_key',
    mattermost_token: '7grgg4r7sjf4dx9qxa7wuybmnh',
    allowed_users: ['bankofdebbie', 'admin', 'sysadmin']
};

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

/**
 * Execute SSH command to VPS
 */
function executeSSHCommand(command) {
    return new Promise((resolve, reject) => {
        const sshCmd = `ssh -i ${config.ssh_key_path} -p ${config.vps_port} -o StrictHostKeyChecking=no -o ConnectTimeout=15 ${config.vps_user}@${config.vps_domain} "${command}"`;
        
        console.log(`Executing SSH command: ${command}`);
        
        exec(sshCmd, { timeout: 30000 }, (error, stdout, stderr) => {
            if (error) {
                console.error(`SSH Error: ${error.message}`);
                reject(new Error(`SSH command failed: ${error.message}`));
                return;
            }
            
            if (stderr) {
                console.warn(`SSH Warning: ${stderr}`);
            }
            
            resolve(stdout.trim());
        });
    });
}

/**
 * Get BTCPay onion address
 */
async function getBTCPayOnion() {
    try {
        const result = await executeSSHCommand('sudo cat /var/lib/docker/volumes/generated_tor_servicesdir/_data/BTCPayServer/hostname 2>/dev/null || echo "pending"');
        return result || 'pending';
    } catch (error) {
        return 'error: ' + error.message;
    }
}

/**
 * Get Bitcoin P2P onion address
 */
async function getBitcoinOnion() {
    try {
        const result = await executeSSHCommand('sudo cat /var/lib/docker/volumes/generated_tor_servicesdir/_data/BTC-P2P/hostname 2>/dev/null || echo "pending"');
        return result || 'pending';
    } catch (error) {
        return 'error: ' + error.message;
    }
}

/**
 * Get system status
 */
async function getSystemStatus() {
    try {
        const commands = [
            'docker ps --format "table {{.Names}}\\t{{.Status}}" | grep -E "(btcpay|bitcoin|tor)" | wc -l',
            'df -h / | grep -v Filesystem | awk "{print \\$3 \\" used / \\" \\$2 \\" total\\"}"',
            'docker logs btcpayserver_bitcoind 2>&1 | grep -i "prune configured" | tail -1 | grep -o "[0-9]* MiB" || echo "10000 MiB"'
        ];
        
        const [containers, disk, pruning] = await Promise.all(
            commands.map(cmd => executeSSHCommand(cmd).catch(err => 'error'))
        );
        
        return {
            containers: containers + ' containers running',
            disk_usage: disk,
            bitcoin_pruning: pruning + ' max storage'
        };
    } catch (error) {
        return { error: error.message };
    }
}

/**
 * Main Mattermost slash command endpoint
 */
app.post('/btcpay', async (req, res) => {
    try {
        console.log('Mattermost request:', JSON.stringify(req.body, null, 2));
        
        const { token, user_name, text, command } = req.body;

        // Validate token
        if (token !== config.mattermost_token) {
            return res.json({ 
                response_type: 'ephemeral',
                text: '❌ Unauthorized: Invalid token' 
            });
        }

        // Check if user is authorized
        if (!config.allowed_users.includes(user_name)) {
            return res.json({ 
                response_type: 'ephemeral',
                text: `❌ Access denied for user: ${user_name}. Contact admin for BTCPay access.` 
            });
        }

        const commandText = (text || '').toLowerCase().trim();
        const isOnionCommand = commandText.includes('onion') || commandText === '' || commandText.includes('addresses');
        const isStatusCommand = commandText.includes('status');
        const isHelpCommand = commandText.includes('help');

        if (isHelpCommand) {
            return res.json({
                response_type: 'ephemeral',
                text: `## BTCPay Server Commands\n\n` +
                      `**Available commands:**\n` +
                      `• \`/btcpay\` or \`/btcpay onion\` - Get onion addresses\n` +
                      `• \`/btcpay status\` - Get system status\n` +
                      `• \`/btcpay help\` - Show this help\n\n` +
                      `**VPS:** ${config.vps_domain}\n` +
                      `**Method:** SSH-based secure retrieval\n` +
                      `**User:** ${user_name} ✅`
            });
        }

        if (isStatusCommand) {
            // Get full system status
            const [btcpayOnion, bitcoinOnion, systemStatus] = await Promise.all([
                getBTCPayOnion(),
                getBitcoinOnion(), 
                getSystemStatus()
            ]);

            const response = {
                response_type: 'in_channel',
                text: `## 📊 BTCPay Server Status Report\n\n` +
                      `**🌐 Domain:** https://${config.vps_domain}\n\n` +
                      `**🧅 Tor Onion Services:**\n` +
                      `• **BTCPay:** \`${btcpayOnion}\`\n` +
                      `• **Bitcoin P2P:** \`${bitcoinOnion}\`\n\n` +
                      `**📊 System Health:**\n` +
                      `• **Containers:** ${systemStatus.containers || 'checking...'}\n` +
                      `• **Storage:** ${systemStatus.disk_usage || 'checking...'}\n` +
                      `• **Bitcoin:** ${systemStatus.bitcoin_pruning || 'Pruned mode'}\n\n` +
                      `**🔒 Security:** Tor-only Bitcoin, Hardened Debian 13\n` +
                      `**📅 Retrieved:** ${new Date().toLocaleString()}\n` +
                      `**👤 Requested by:** ${user_name}`
            };

            return res.json(response);
        }

        if (isOnionCommand) {
            // Get onion addresses only
            const [btcpayOnion, bitcoinOnion] = await Promise.all([
                getBTCPayOnion(),
                getBitcoinOnion()
            ]);

            const response = {
                response_type: 'in_channel',
                text: `## 🧅 BTCPay Tor Onion Addresses\n\n` +
                      `**🌐 Domain:** https://${config.vps_domain}\n\n` +
                      `**🧅 Tor Hidden Services:**\n` +
                      `• **BTCPay Server:** \`${btcpayOnion}\`\n` +
                      `• **Bitcoin P2P:** \`${bitcoinOnion}\`\n\n` +
                      `**🔐 Access Methods:**\n` +
                      `• **Clearnet:** https://${config.vps_domain}\n` +
                      `• **Tor Browser:** http://${btcpayOnion}\n\n` +
                      `**⚡ API Endpoints:**\n` +
                      `• **REST API:** https://${config.vps_domain}/api\n` +
                      `• **Tor API:** http://${btcpayOnion}/api\n\n` +
                      `**📅 Retrieved:** ${new Date().toLocaleString()}\n` +
                      `**👤 Requested by:** ${user_name}`
            };

            return res.json(response);
        }

        // Default response
        return res.json({
            response_type: 'ephemeral',
            text: `❓ Unknown command: "${commandText}"\n\n` +
                  `Use \`/btcpay help\` for available commands.\n\n` +
                  `**Quick commands:**\n` +
                  `• \`/btcpay\` - Get onion addresses\n` +
                  `• \`/btcpay status\` - Get system status`
        });

    } catch (error) {
        console.error('API Error:', error);
        return res.json({
            response_type: 'ephemeral',
            text: `❌ **Error retrieving BTCPay information:**\n\`\`\`\n${error.message}\n\`\`\`\n\nPlease check VPS connectivity.`
        });
    }
});

/**
 * Health check endpoint
 */
app.get('/health', (req, res) => {
    res.json({ 
        status: 'healthy', 
        service: 'Mattermost BTCPay Local API',
        vps_target: config.vps_domain,
        method: 'SSH-based commands',
        timestamp: new Date().toISOString()
    });
});

/**
 * Test endpoint
 */
app.get('/test', async (req, res) => {
    try {
        const [btcpayOnion, bitcoinOnion] = await Promise.all([
            getBTCPayOnion(),
            getBitcoinOnion()
        ]);
        
        res.json({
            vps_domain: config.vps_domain,
            btcpay_onion: btcpayOnion,
            bitcoin_onion: bitcoinOnion,
            method: 'SSH retrieval',
            timestamp: new Date().toISOString()
        });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
});

/**
 * Start server
 */
app.listen(PORT, '127.0.0.1', () => {
    console.log(`🚀 Mattermost BTCPay Local API running on localhost:${PORT}`);
    console.log(`🎯 Target VPS: ${config.vps_domain}:${config.vps_port}`);
    console.log(`🔑 Method: SSH-based command execution`);
    console.log(`💡 Endpoints:`);
    console.log(`   POST /btcpay - Mattermost slash command handler`);
    console.log(`   GET  /test - Test SSH connectivity`);
    console.log(`   GET  /health - Health check`);
    console.log(`\n🔧 Mattermost Slash Command Setup:`);
    console.log(`   Command: /btcpay`);
    console.log(`   URL: http://localhost:${PORT}/btcpay`);
    console.log(`   Token: ${config.mattermost_token}`);
    console.log(`   Method: POST`);
    console.log(`\n⚠️  IMPORTANT: Update ssh_key_path in config before running!`);
    console.log(`   Current path: ${config.ssh_key_path}`);
});

// Graceful shutdown
process.on('SIGTERM', () => {
    console.log('🛑 Shutting down local API server...');
    process.exit(0);
});

module.exports = app;