import{createServer}from'node:http';import{readFile}from'node:fs/promises';import{resolve,extname,sep}from'node:path';import{fileURLToPath}from'node:url';import{validateData,LIMITS}from'./engine.mjs';
const root=fileURLToPath(new URL('../public/',import.meta.url));
const send=(res,status,data)=>{res.writeHead(status,{'Content-Type':'application/json; charset=utf-8','Cache-Control':'no-store','X-Content-Type-Options':'nosniff'});res.end(JSON.stringify(data));};
export function createApp(){return createServer(async(req,res)=>{try{
 const u=new URL(req.url,'http://localhost');
 if(u.pathname==='/api/validate'){
  if(req.method!=='POST'){res.setHeader('Allow','POST');return send(res,405,{error:'METHOD_NOT_ALLOWED'});}
  if(!/^application\/json(?:;|$)/i.test(req.headers['content-type']??''))return send(res,415,{error:'JSON_REQUIRED'});
  let bytes=0,tooLarge=false,chunks=[];for await(const c of req){bytes+=c.length;if(bytes>LIMITS.bytes){tooLarge=true;chunks=[];}else if(!tooLarge)chunks.push(c);}if(tooLarge)return send(res,413,{error:'BODY_TOO_LARGE'});
  let body;try{body=JSON.parse(Buffer.concat(chunks).toString('utf8'));}catch{return send(res,400,{error:'INVALID_JSON'});}
  if(!body||typeof body!=='object'||Array.isArray(body)||typeof body.key!=='string'||!Object.hasOwn(body,'data'))return send(res,400,{error:'INVALID_ENVELOPE'});
  try{const result=validateData(body.key,body.data,{mutate:body.mutate===true});return send(res,result.valid?200:422,result);}catch(e){return send(res,400,{error:e.message});}
 }
 if(req.method!=='GET'&&req.method!=='HEAD')return send(res,405,{error:'METHOD_NOT_ALLOWED'});
 const path=resolve(root,'.'+decodeURIComponent(u.pathname==='/'?'/index.html':u.pathname));if(!path.startsWith(root.endsWith(sep)?root:root+sep))return send(res,403,{error:'FORBIDDEN'});
 let data;try{data=await readFile(path);}catch{return send(res,404,{error:'NOT_FOUND'});}
 const mime={'.html':'text/html; charset=utf-8','.js':'text/javascript; charset=utf-8','.css':'text/css; charset=utf-8','.json':'application/json; charset=utf-8','.txt':'text/plain; charset=utf-8'};
 res.writeHead(200,{'Content-Type':mime[extname(path)]??'application/octet-stream','X-Content-Type-Options':'nosniff','Content-Length':data.length});res.end(req.method==='HEAD'?undefined:data);
 }catch{if(!res.headersSent)send(res,400,{error:'BAD_REQUEST'});else res.end();}});}
if(process.argv[1]&&resolve(process.argv[1])===fileURLToPath(import.meta.url)){const server=createApp();server.requestTimeout=15000;server.headersTimeout=10000;server.listen(Number(process.env.PORT||8402),'127.0.0.1',()=>console.log('Ajv workshop http://127.0.0.1:'+(process.env.PORT||8402)));for(const signal of['SIGINT','SIGTERM'])process.on(signal,()=>server.close());}
