import{logger as e}from"../../logger/index.mjs";import{mutateScore as t}from"./analysis/calculateScore.mjs";import{runSingleAudit as n}from"./seoAudit.service.mjs";import{AuditJobModel as r,AuditJobStatus as i}from"../../models/auditJob.model.mjs";import{AuditPageModel as a,AuditPageStatus as o}from"../../models/auditPage.model.mjs";import{load as s}from"cheerio";let c=!1;const l=async e=>{try{let{origin:t}=new URL(e),n=`${t}/sitemap.xml`,r=await fetch(n,{method:`GET`,headers:{"User-Agent":`Mozilla/5.0 (compatible; SEO-Audit-Bot/1.0)`},signal:AbortSignal.timeout(1e4)});if(!r.ok)return[e];let i=s(await r.text(),{xmlMode:!0}),a=[];i(`loc`).each((e,t)=>{let n=i(t).text().trim();n&&a.push(n)}),i(`xhtml\\:link[rel="alternate"], link[rel="alternate"]`).each((e,t)=>{let n=i(t).attr(`href`)?.trim();n&&n!==`x-default`&&a.push(n)});let o=[...new Set(a)];return o.length>0?o:[e]}catch{return[e]}},u=async(t,n,s)=>{let c=await r.findOne({targetUrl:t,status:{$in:[i.PENDING,i.RUNNING]}});if(c)return c._id.toString();let l=s&&s.length>0?[...new Set(s)].slice(0,10):[t],u=await r.create({targetUrl:t,userId:n,status:i.PENDING,totalPageCount:l.length});for(let e of l)await a.create({jobId:u._id,url:e,status:o.PENDING}).catch(()=>{});return m().catch(t=>e.error(t)),u._id.toString()},d=async e=>!!await r.findByIdAndUpdate(e,{status:i.CANCELLED}),f=async e=>!!await r.findByIdAndUpdate(e,{status:i.PAUSED}),p=async t=>await r.findByIdAndUpdate(t,{status:i.RUNNING})?(m().catch(t=>e.error(t)),!0):!1,m=async()=>{if(!c){c=!0;try{for(;;){let s=await r.findOne({status:{$in:[i.PENDING,i.RUNNING]}}).sort({createdAt:1});if(!s)break;s.status===i.PENDING&&(s.status=i.RUNNING,await s.save());let c=await r.findById(s._id);if(!c||c.status===i.CANCELLED||c.status===i.PAUSED){e.info(`Job ${s._id} is ${c?.status??`missing`} — stopping processor`);break}let l=await a.findOne({jobId:s._id,status:o.PENDING});if(!l){await a.exists({jobId:s._id,status:{$in:[o.PENDING,o.RUNNING]}})||(s.status=i.COMPLETED,s.progress=100,await s.save());break}l.status=o.RUNNING,await l.save();try{let{events:e}=await n(l.url,()=>{}),r={score:0,totalScore:0};for(let n of e)r=t(r,n);l.status=o.COMPLETED,l.results=e,l.score=Math.round(r.totalScore>0?r.score/r.totalScore*100:0),await l.save();let i=await a.countDocuments({jobId:s._id}),c=await a.countDocuments({jobId:s._id,status:o.COMPLETED});s.totalPageCount=i,s.completedPageCount=c,s.progress=Math.round(c/i*100),await s.save()}catch(t){e.error(`Failed to audit page ${l.url}:`,t),l.status=o.FAILED,l.error=String(t),await l.save()}await new Promise(e=>setTimeout(e,3e4))}}finally{c=!1}}},h=async e=>{let t=await r.findById(e);return t?{job:t,pages:await a.find({jobId:e}).select(`url status score error results`)}:null};export{d as cancelAuditJob,l as discoverUrlsFromSitemap,h as getAuditJobStatus,f as pauseAuditJob,m as processAuditJobs,p as resumeAuditJob,u as startRecursiveAuditJob};
//# sourceMappingURL=recursiveAudit.service.mjs.map