/**
* GET /status — daemon status page (formerly /).
*
* Scannable cards (Identity, Service, Data, Bootstrap keys) so the operator
* can see what's running at a glance instead of scanning walls of text.
* Bootstrap keys are collapsed by default since the operator only needs
* them when joining a peer.
*
* Linked from the /admin page; not in the main nav.
*/
import b4a from 'b4a'
import { layout, escapeHtml } from '../helpers.js'
export async function renderStatus (svc, ctx) {
const prefix = (ctx && ctx.prefix) || ''
const orgs = await svc.modules.orgs.list()
// Aggregate across every per-repo and per-org issue tracker.
const counts = await svc.issueRegistry.counts()
const users = await svc.identityRegistry.listUsers().catch(() => [])
const handlers = svc.listHandlers()
const swarmTopic = svc.swarm ? b4a.toString(svc.swarm.topic, 'hex') : null
const swarmPeers = svc.swarm ? svc.swarm.connections : 0
const id = svc.identity
const idShort = id ? id.publicKeyHex.slice(0, 16) + '…' + id.publicKeyHex.slice(-8) : '(none)'
const sessionId = ctx && ctx.identity && ctx.identity.publicKey
? ctx.identity.publicKey.slice(0, 16) + '…' + ctx.identity.publicKey.slice(-8)
: '(unauthenticated)'
const sessionTransport = ctx ? ctx.transport : '?'
const bk = svc.bootstrapKeys || {}
const orgsKey = bk.orgs || svc.modules.orgs.keyHex
const identityKey = bk.identity || null
const repoEventLogKey = bk.repoEventLog || null
// Per-scope issue bootstrap keys — built on demand from the registry.
// Displayed under the "Bootstrap keys" disclosure only when >0 scopes exist.
const issueKeys = await svc.issueRegistry.keys()
const issueKeyRows = [
...Object.entries(issueKeys.repos || {}).map(([name, key]) => ({ label: 'issues.repo.' + name, key })),
...Object.entries(issueKeys.orgs || {}).map(([name, key]) => ({ label: 'issues.org.' + name, key }))
]
const transports = [
{ name: 'uds', enabled: !!svc.uds, info: svc.uds ? svc.uds.path : '—' },
{ name: 'http', enabled: !!svc.http, info: svc.http ? '127.0.0.1:' + (svc.http.port || '?') : '—' },
{
name: 'swarm',
enabled: !!svc.swarm,
info: svc.swarm ? `topic ${swarmTopic.slice(0, 16)}… · ${swarmPeers} peer${swarmPeers === 1 ? '' : 's'}` : '—'
}
]
const body = `
<h1>status</h1>
<div class="card">
<h2>Identity</h2>
<div class="row"><div class="label">daemon</div><div title="${id ? escapeHtml(id.publicKeyHex) : ''}" class="mono" style="font-size:0.8rem">${escapeHtml(idShort)}</div></div>
<div class="row"><div class="label">session</div><div class="mono" style="font-size:0.8rem">${escapeHtml(sessionId)}</div></div>
<div class="row"><div class="label">transport</div><div>${escapeHtml(sessionTransport)}</div></div>
</div>
<div class="card">
<h2>Service</h2>
<div class="row"><div class="label">name</div><div>${escapeHtml(svc.name)}</div></div>
<div class="row"><div class="label">handlers</div><div>${handlers.length}</div></div>
<div class="row"><div class="label">mounts</div><div>${svc.listMounts().join(', ')}</div></div>
${transports.map(tr => `
<div class="row">
<div class="label">${escapeHtml(tr.name)}</div>
<div class="meta">${tr.enabled ? 'on · ' + escapeHtml(tr.info) : 'off'}</div>
</div>`).join('')}
</div>
<div class="card">
<h2>Data</h2>
<div class="row"><div class="label">orgs</div><div>${orgs.length} (${orgs.filter(o => o.type === 'group').length} group${orgs.filter(o => o.type === 'group').length === 1 ? '' : 's'}, ${orgs.filter(o => o.type === 'user').length} user${orgs.filter(o => o.type === 'user').length === 1 ? '' : 's'})</div></div>
<div class="row"><div class="label">issues</div><div>${counts.total} (${counts.open} open, ${counts.closed} closed)</div></div>
<div class="row"><div class="label">users</div><div>${Array.isArray(users) ? users.length : '?'}</div></div>
</div>
<div class="card">
<details>
<summary style="cursor:pointer;color:#8b949e;font-size:0.75rem;text-transform:uppercase;letter-spacing:0.5px;">Bootstrap keys</summary>
<div class="meta" style="margin:0.5rem 0">Copy these into a peer's <code>opts.mounts</code> to join this deployment.</div>
<div class="row"><div class="label">orgs.bootstrapKey</div><div class="mono" style="font-size:0.7rem">${escapeHtml(orgsKey || '(none)')}</div></div>
<div class="row"><div class="label">identity.bootstrapKey</div><div class="mono" style="font-size:0.7rem">${escapeHtml(identityKey || '(none)')}</div></div>
<div class="row"><div class="label">repoEventLog.coreKey</div><div class="mono" style="font-size:0.7rem">${escapeHtml(repoEventLogKey || '(none)')}</div></div>
${issueKeyRows.length > 0 ? issueKeyRows.map(r =>
`<div class="row"><div class="label">${escapeHtml(r.label)}</div><div class="mono" style="font-size:0.7rem">${escapeHtml(r.key || '(none)')}</div></div>`
).join('') : '<div class="row"><div class="label">issues</div><div class="meta">(no issue trackers created yet — they instantiate on first access per repo/org)</div></div>'}
${swarmTopic ? `<div class="row"><div class="label">swarm.topic</div><div class="mono" style="font-size:0.7rem">${escapeHtml(swarmTopic)}</div></div>` : ''}
</details>
</div>
`
return layout('status', '/status', body, ctx)
}