import Module from"./module.mjs";import System from"./system.mjs";import World from"./world.mjs";import{ReleaseData}from"../../common/config.mjs";import Collection from"../../common/utils/collection.mjs";import{PACKAGE_AVAILABILITY_CODES}from"../../common/constants.mjs";export default class PreviewCompatibility{constructor(e){if(!(e instanceof ReleaseData))throw new Error("You must provide an instance of ReleaseData to the PreviewCompatibility constructor.");if(e.version===globalThis.release.version)throw new Error("You may not preview compatibility for the current software release.");this.release=e,this.release.maxGeneration=globalThis.release.maxGeneration,this.release.maxStableGeneration=globalThis.release.maxStableGeneration}release;modules=new Collection;systems=new Collection;worlds=new Collection;async evaluate(){await this.getRepositoryPackages(),await this.testCompatibility();for(const e of this.modules.keys())Module.packages.has(e)||this.modules.delete(e)}async getRepositoryPackages(){await this.#e(System,this.systems,{installedOnly:!0}),await this.#e(Module,this.modules,{installedOnly:!1}),this.worlds=packages.World.packages.reduce(((e,s)=>{const t=s.clone();return t.system=this.systems.get(s._source.system),t.compatibility.maximum=t._source.compatibility.maximum,e.set(t.id,t)}),new Collection)}async testCompatibility(){const e=PACKAGE_AVAILABILITY_CODES,{release:s,modules:t,systems:a,worlds:i}=this;for(const e of t.values())e.availability=Module.testAvailability(e,{release:s});for(const e of a.values())e.availability=System.testAvailability(e,{release:s});for(const o of i.values())o.availability=World.testAvailability(o,{release:s,modules:t,systems:a,systemAvailabilityThreshold:e.UNVERIFIED_GENERATION});for(const s of System.packages.keys()){const i=a.get(s);await i._testRequiredDependencies(t)||(i.availability=e.MISSING_DEPENDENCY)}for(const s of Module.packages.keys()){const i=t.get(s);await i._testRequiredDependencies(t)||(i.availability=e.MISSING_DEPENDENCY);await i._testSupportedSystems(a)||(i.availability=e.UNVERIFIED_SYSTEM)}for(const s of World.packages.keys()){const a=i.get(s);await a._testRequiredDependencies(t)||(a.availability=e.MISSING_DEPENDENCY)}}async#e(e,s,{installedOnly:t=!0}={}){s.clear();const a=e.getPackages(),i=await e.getRepositoryPackages(),o=await e.getRepositoryPackages({release:this.release});for(const e of o.packages.values())t&&!a.has(e.id)||s.set(e.id,e);for(const e of i.packages.values())t&&!a.has(e.id)||s.has(e.id)||s.set(e.id,e);let l=[];for(const t of a.values())s.has(t.id)||(l.length>=8&&(await Promise.all(l),l=[]),l.push(e.fromRemoteManifest(t.manifest).then((e=>{s.set(t.id,e)})).catch((()=>{s.set(t.id,t.clone())}))));await Promise.all(l)}vend(){return{version:this.release.version,world:this.worlds.map((e=>e.vend())),system:this.systems.map((e=>e.vend())),module:this.modules.map((e=>e.vend()))}}static async test(e={}){const s=new this(new ReleaseData({channel:"stable",node_version:16,...e}));return await s.evaluate(),s}}