import { Router, Request, Response } from 'express';
import { param } from '../utils/params';
import { registerSlug, unregisterSlug, listSlugs } from '../services/registry.service';

const router = Router();

// SECURITY: defense-in-depth slug validation. The CCP enforces ^[a-z0-9-]+$
// upstream via Zod, but the registry slug is later interpolated into
// filesystem paths (backupsDirFor, etc.), so we validate independently here.
// A poisoned registry entry could otherwise let a compromised or buggy CCP
// escape AGENT_DATA_DIR.
const SLUG_RE = /^[a-z0-9-]{2,50}$/;

// POST /instances/register — Register a slug→basePath mapping
router.post('/instances/register', async (req: Request, res: Response) => {
  const { slug, basePath, composeProject } = req.body;
  if (!slug || !basePath || !composeProject) {
    res.status(400).json({ error: 'VALIDATION', message: 'slug, basePath, and composeProject required' });
    return;
  }
  if (typeof slug !== 'string' || !SLUG_RE.test(slug)) {
    res.status(400).json({ error: 'VALIDATION', message: 'Invalid slug format (expected ^[a-z0-9-]{2,50}$)' });
    return;
  }
  await registerSlug(slug, basePath, composeProject);
  res.json({ registered: slug });
});

// DELETE /instances/:slug — Unregister slug
router.delete('/instances/:slug', async (req: Request, res: Response) => {
  const slug = param(req, 'slug');
  if (!SLUG_RE.test(slug)) {
    res.status(400).json({ error: 'VALIDATION', message: 'Invalid slug format' });
    return;
  }
  await unregisterSlug(slug);
  res.json({ unregistered: slug });
});

// GET /instances — List all managed slugs
router.get('/instances', async (_req: Request, res: Response) => {
  const slugs = await listSlugs();
  res.json(slugs);
});

export default router;
