import fs from 'fs';
import fsp from 'fs/promises';
import http from 'http';
import path from 'path';
import { DATA_PATH } from '../helpers/paths';

const ROUTE_PREFIX = '/deepfilter-assets/';
const ALLOWED_CDN_PATH_PREFIX =
  'AI/models/datas/noise_suppression/deepfilternet3/';
const CACHE_DIR = path.join(DATA_PATH, 'deepfilter-assets');

const guessContentType = (filePath: string): string => {
  if (filePath.endsWith('.wasm')) return 'application/wasm';
  if (filePath.endsWith('.gz')) return 'application/gzip';
  if (filePath.endsWith('.json')) return 'application/json';
  return 'application/octet-stream';
};

const sendFile = async (res: http.ServerResponse, filePath: string) => {
  const stat = await fsp.stat(filePath);
  res.writeHead(200, {
    'Content-Type': guessContentType(filePath),
    'Content-Length': stat.size,
    'Cache-Control': 'public, max-age=31536000, immutable'
  });
  fs.createReadStream(filePath).pipe(res);
};

const deepfilterAssetsRouteHandler = async (
  req: http.IncomingMessage,
  res: http.ServerResponse
) => {
  const routePath = (req.url || '').split('?')[0] || '';
  if (!routePath.startsWith(ROUTE_PREFIX)) {
    res.writeHead(404, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ error: 'Not found' }));
    return;
  }

  let relativePath = '';
  try {
    relativePath = decodeURIComponent(routePath.slice(ROUTE_PREFIX.length));
  } catch {
    res.writeHead(400, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ error: 'Invalid path' }));
    return;
  }

  if (!relativePath.startsWith(ALLOWED_CDN_PATH_PREFIX)) {
    res.writeHead(403, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ error: 'Forbidden' }));
    return;
  }

  const resolvedPath = path.resolve(CACHE_DIR, relativePath);
  const cacheBasePath = path.resolve(CACHE_DIR);
  const relativeToBase = path.relative(cacheBasePath, resolvedPath);
  if (relativeToBase.startsWith('..') || path.isAbsolute(relativeToBase)) {
    res.writeHead(403, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ error: 'Forbidden' }));
    return;
  }

  try {
    await sendFile(res, resolvedPath);
    return;
  } catch {
    res.writeHead(404, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ error: 'DeepFilter asset not bundled on server' }));
  }
};

export { deepfilterAssetsRouteHandler };
