/**
 * SSH Discovery API Endpoint
 * 
 * POST /api/discover - Discover all hosts via SSH and return their status
 */

import { Router } from 'express';
import { execSync } from 'child_process';
import { homedir } from 'os';
import { getHostConfigs } from '../config';
import { DiscoveryResponse } from '../types';

const router = Router();

interface HostDiscoveryResult {
  name: string;
  ip: string;
  online: boolean;
  containers?: string[];
  services?: string[];
  vms?: Array<{ id: string; name: string; status: string; type: 'lxc' | 'qemu' }>;
  error?: string;
}

async function discoverHost(
  name: string,
  ip: string,
  sshUser: string,
  sshKeyPath?: string,
  sshPort?: number,
  hostType?: string
): Promise<HostDiscoveryResult> {
  try {
    const keyPath = (sshKeyPath || `${homedir()}/.ssh/id_ed25519`).replace(/^~/, homedir());
    console.error(`DEBUG: ${name} keyPath=${keyPath}, user=${sshUser}`);
    const keyArg = `-i ${keyPath}`;
    const portArg = sshPort && sshPort !== 22 ? `-p ${sshPort}` : '';
    
    const dockerCmd = `ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no ${keyArg} ${portArg} ${sshUser}@${ip} "docker ps --format '{{.Names}}'" 2>/dev/null`;
    const dockerOutput = execSync(dockerCmd, { encoding: 'utf-8', timeout: 15000 });
    const containers = dockerOutput.trim().split('\n').filter(c => c.trim());
    
    let services: string[] = [];
    if (hostType !== 'proxmox') {
      try {
        const systemdCmd = `ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no ${keyArg} ${portArg} ${sshUser}@${ip} "systemctl list-units --type=service --state=running --no-pager --no-legend --quiet | awk '{print \\$1}'" 2>/dev/null`;
        const systemdOutput = execSync(systemdCmd, { encoding: 'utf-8', timeout: 10000 });
        services = systemdOutput.trim().split('\n').filter(s => s.trim());
      } catch {
        console.error(`DEBUG: ${name} systemd discovery failed`);
      }
    }
    
    let vms: Array<{ id: string; name: string; status: string; type: 'lxc' | 'qemu' }> = [];
    if (hostType === 'proxmox' || name === 'proxmox') {
      try {
        const lxcCmd = `ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no ${keyArg} ${portArg} ${sshUser}@${ip} "pct list" 2>/dev/null`;
        const lxcOutput = execSync(lxcCmd, { encoding: 'utf-8', timeout: 10000 });
        const lxcLines = lxcOutput.trim().split('\n').slice(1);
        for (const line of lxcLines) {
          const parts = line.trim().split(/\s+/);
          if (parts.length >= 2) {
            vms.push({ id: parts[0], name: parts[1], status: parts[2] || 'unknown', type: 'lxc' });
          }
        }
        
        const vmCmd = `ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no ${keyArg} ${portArg} ${sshUser}@${ip} "qm list" 2>/dev/null`;
        const vmOutput = execSync(vmCmd, { encoding: 'utf-8', timeout: 10000 });
        const vmLines = vmOutput.trim().split('\n').slice(1);
        for (const line of vmLines) {
          const parts = line.trim().split(/\s+/);
          if (parts.length >= 2) {
            vms.push({ id: parts[0], name: parts[1], status: parts[2] || 'unknown', type: 'qemu' });
          }
        }
      } catch {
        console.error(`DEBUG: ${name} Proxmox discovery failed`);
      }
    }
    
    return {
      name,
      ip,
      online: true,
      containers,
      services: services.length > 0 ? services : undefined,
      vms: vms.length > 0 ? vms : undefined,
    };
  } catch (error: any) {
    return {
      name,
      ip,
      online: false,
      containers: [],
      error: error.message || 'Discovery failed',
    };
  }
}

// POST /api/discover - Discover all hosts via SSH
router.post('/discover', async (req, res) => {
  try {
    const hosts = getHostConfigs();
    
    if (hosts.length === 0) {
      const response: DiscoveryResponse = {
        hosts: [],
        timestamp: new Date().toISOString(),
        errors: ['No hosts configured'],
      };
      return res.json(response);
    }

    const results: HostDiscoveryResult[] = [];
    for (const host of hosts) {
      try {
        const keyPath = host.sshKeyPath?.replace(/^~/, homedir());
        const result = await discoverHost(
          host.name,
          host.ip,
          host.sshUser,
          keyPath,
          host.sshPort,
          host.hostType
        );
        results.push(result);
      } catch (error: any) {
        results.push({
          name: host.name,
          ip: host.ip,
          online: false,
          containers: [],
          error: error.message || 'Discovery failed'
        });
      }
    }
    
    const errors: string[] = [];
    results.forEach((result: HostDiscoveryResult) => {
      if (!result.online && result.error) {
        errors.push(`${result.name}: ${result.error}`);
      }
    });

    const response: DiscoveryResponse = {
      hosts: results.map(r => ({
        name: r.name,
        ip: r.ip,
        online: r.online,
        containers: r.containers,
        services: r.services,
        vms: r.vms,
      })),
      timestamp: new Date().toISOString(),
      errors,
    };

    res.json(response);
  } catch (error: any) {
    const response: DiscoveryResponse = {
      hosts: [],
      timestamp: new Date().toISOString(),
      errors: [error.message || 'Discovery failed'],
    };
    res.status(500).json(response);
  }
});

export default router;
