import { createRouter } from '../../create-router';
import { getSlskdServerUrl } from './sidecar-server';

// Thin reverse-proxy for /api/slskd/*. The platform's ONLY job here is AUTH + FORWARDING: this router
// mounts under the protected /api tree (userMiddleware upstream authenticates the owner), then forwards
// the subpath + query + body to the officer-slskd sidecar, which OWNS the slskd contract and injects the
// slskd API key. The platform holds no slskd credentials.
//
// This is a catch-all with no routes of its own: the full /api/slskd/* contract is documented at the top
// of the sidecar's fetch handler (src/servers/sidecar/slskd/index.ts). That contract covers both slskd's
// own API (/api/v0/searches, /api/v0/transfers, …) and the sidecar's Officer-owned routes (/_officer/*,
// features slskd has no concept of). Both are opaque from here — this file never grows Soulseek logic.

export const slskdRouter = createRouter();

const PREFIX = '/api/slskd';

slskdRouter.all('/*', async (ctx) => {
  const baseUrl = getSlskdServerUrl();
  if (!baseUrl) return ctx.text('slskd sidecar not available', 503);

  const url = new URL(ctx.req.url);
  const subpath = url.pathname.slice(PREFIX.length) || '/';
  const target = `${baseUrl}${subpath}${url.search}`;

  const method = ctx.req.method;
  const headers: Record<string, string> = {};
  const contentType = ctx.req.header('content-type');
  if (contentType) headers['Content-Type'] = contentType;
  const range = ctx.req.header('range');
  if (range) headers['Range'] = range;
  // Forward the authenticated user id so the sidecar can serve its own Officer-owned routes (/_officer/*,
  // e.g. favourite peers) against Postgres. The sidecar binds loopback only, so this header is trusted.
  headers['X-Officer-User'] = String(ctx.get('user').id);

  const hasBody = method !== 'GET' && method !== 'HEAD';

  let upstream: Response;
  try {
    upstream = await fetch(target, {
      method,
      headers,
      body: hasBody ? await ctx.req.arrayBuffer() : undefined,
    });
  } catch (err) {
    console.error('[slskd] proxy fetch failed', { target, error: String(err) });
    return ctx.text('slskd sidecar unreachable', 502);
  }

  return new Response(upstream.body, { status: upstream.status, headers: new Headers(upstream.headers) });
});
