import { NextRequest, NextResponse } from 'next/server'
import { readFileSync } from 'node:fs'
import { execFileSync } from 'node:child_process'
import { requireRole } from '@/lib/auth'

interface DiscoveredGateway {
  user: string
  port: number
  active: boolean
  description: string
}

/**
 * GET /api/gateways/discover
 * Discovers OpenClaw gateways via systemd services and port scanning.
 * Does not require filesystem access to other users' configs.
 */
export async function GET(request: NextRequest) {
  const auth = requireRole(request, 'viewer')
  if ('error' in auth) return NextResponse.json({ error: auth.error }, { status: auth.status })

  const discovered: DiscoveredGateway[] = []

  // Parse systemd services for openclaw-gateway instances
  try {
    const output = execFileSync('systemctl', [
      'list-units', '--type=service', '--plain', '--no-legend', '--no-pager',
    ], { encoding: 'utf-8', timeout: 3000 })

    const gwLines = output.split('\n').filter(l => l.includes('openclaw') && l.includes('gateway'))

    for (const line of gwLines) {
      // e.g. "openclaw-gateway@quant.service loaded active running OpenClaw Gateway (quant)"
      const parts = line.trim().split(/\s+/)
      const serviceName = parts[0] || ''
      const state = parts[2] || '' // active/inactive
      const description = parts.slice(4).join(' ') // "OpenClaw Gateway (quant)"

      // Extract user from service name
      let user = ''
      const templateMatch = serviceName.match(/openclaw-gateway@(\w+)\.service/)
      if (templateMatch) {
        user = templateMatch[1]
      } else {
        // Custom service name like "openclaw-leads-gateway.service"
        const customMatch = serviceName.match(/openclaw-(\w+)-gateway\.service/)
        if (customMatch) user = customMatch[1]
      }
      if (!user) continue

      // Find the port by checking what openclaw-gateway processes are listening on
      let port = 0
      try {
        const configPath = `/home/${user}/.openclaw/openclaw.json`
        const raw = readFileSync(configPath, 'utf-8')
        const config = JSON.parse(raw)
        if (typeof config?.gateway?.port === 'number') port = config.gateway.port
      } catch {
        // Can't read config — try to detect from ss output
      }

      // If we couldn't read config, try finding port via ss for the service PID
      if (!port) {
        try {
          const pidOutput = execFileSync('systemctl', [
            'show', serviceName, '--property=ExecMainPID', '--value',
          ], { encoding: 'utf-8', timeout: 2000 }).trim()
          const pid = parseInt(pidOutput, 10)
          if (pid > 0) {
            const ssOutput = execFileSync('ss', ['-ltnp'], {
              encoding: 'utf-8', timeout: 2000,
            })
            const pidPattern = `pid=${pid},`
            for (const ssLine of ssOutput.split('\n')) {
              if (ssLine.includes(pidPattern)) {
                const portMatch = ssLine.match(/:(\d+)\s/)
                if (portMatch) { port = parseInt(portMatch[1], 10); break }
              }
            }
          }
        } catch { /* ignore */ }
      }

      if (!port) continue

      discovered.push({
        user,
        port,
        active: state === 'active',
        description: description.replace(/[()]/g, '').trim(),
      })
    }
  } catch {
    // systemctl not available or failed — fall back silently
  }

  return NextResponse.json({ gateways: discovered })
}
