import http from 'node:http';
import { createReadStream } from 'node:fs';
import { stat } from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..');
const types={'.html':'text/html; charset=utf-8','.js':'text/javascript; charset=utf-8','.css':'text/css; charset=utf-8','.png':'image/png','.jpg':'image/jpeg','.woff2':'font/woff2','.mp4':'video/mp4','.json':'application/json','.zip':'application/zip'};
export async function serve(port=0){
 const server=http.createServer(async(req,res)=>{
  try{const url=new URL(req.url,'http://localhost');let relative=decodeURIComponent(url.pathname);if(relative.endsWith('/'))relative+='index.html';
   const filename=path.resolve(root,'.'+relative);
   if(!filename.startsWith(root+path.sep)||relative.includes('/.')){res.writeHead(403).end();return;}
   const info=await stat(filename);if(!info.isFile())throw new Error('Missing');
   const headers={'Content-Type':types[path.extname(filename)]||'application/octet-stream','Cache-Control':'no-store','Accept-Ranges':'bytes'};
   const range=req.headers.range?.match(/^bytes=(\d+)-(\d*)$/);
   if(range){const start=Number(range[1]),end=range[2]?Math.min(Number(range[2]),info.size-1):info.size-1;if(start>end){res.writeHead(416,{'Content-Range':`bytes */${info.size}`}).end();return;}res.writeHead(206,{...headers,'Content-Length':end-start+1,'Content-Range':`bytes ${start}-${end}/${info.size}`});createReadStream(filename,{start,end}).pipe(res);}
   else{res.writeHead(200,{...headers,'Content-Length':info.size});if(req.method==='HEAD')res.end();else createReadStream(filename).pipe(res);}
  }catch{res.writeHead(404).end('Not found');}
 });
 await new Promise(resolve=>server.listen(port,'127.0.0.1',resolve));return{server,url:`http://127.0.0.1:${server.address().port}`};
}
if(process.argv[1]===fileURLToPath(import.meta.url)){const{url}=await serve(Number(process.env.PORT)||4178);console.log(`ELEKTRING preview: ${url}`);}
