const{InternalSchema:e}=require("@holepunchto/keet-core-schemas"),{InternalOperation:t,UpgradeOperation:i,GenesisOperation:n,AddPluginOperation:a}=e.Operations,{FEATURES:s,isFeatureSupported:r,CURRENT_ABI:o,MIN_ABIS:l}=require("@holepunchto/keet-core-api");module.exports=class{static Operations=new Set([t.TYPE]);constructor(e){this.view=e,this.members=null,this.config=null,this._bee=null}initialize(){this.members=this.view.members,this.config=this.view.config,this._bee=this.view.bee}async _getCodeVersion(t){const i=await t.get(e.CodeVersionKey,e.UpgraderEncoding);return i?i.value:0}async getCodeVersion(e=-1){if(-1===e)return this._getCodeVersion(this._bee);const t=this._bee.checkout(e);try{return await this._getCodeVersion(t)}finally{await t.close()}}updateCodeVersion(t){return this._bee.put(e.CodeVersionKey,t,e.UpgraderEncoding)}setExperimentalMode(){return this._bee.put(e.ExperimentalModeKey,1,e.UpgraderEncoding)}getExperimentalMode(){return this._bee.get(e.ExperimentalModeKey,e.UpgraderEncoding)}async isExperimentalMode(){const e=await this.getExperimentalMode();return!!e&&1===e.value}async listPlugins(){const t=[];for await(const{value:i}of this._bee.createReadStream(e.PluginsEncoding))t.push(i);return t}async updatePlugin(t,{key:i,length:n,fork:a}){const s=await this.listPlugins();let r=-1;for(let e=0;e<s.length;e++)if(s[e].name===t){r=e;break}if(-1===r){const t={...e.PluginsEncoding.keyEncoding.encodeRange({}),reverse:!0},i=await this._bee.peek(t);r=i?e.PluginsEncoding.keyEncoding.decode(i.key)+1:0}await this._bee.put(r,{name:t,key:i,length:n,fork:a},e.PluginsEncoding)}async _applyGenesisOperation(e,{id:t}){if(this.view.core.length>0)return;const{experimental:i,bootstrap:n,version:a}=e.value.value;await this.view.devices.addBootstrapMember(t.key,n.noisePublicKey),await this.updateCodeVersion(a),i&&await this.setExperimentalMode()}async _applyUpgradeOperation(e){const{version:t}=e.value.value,i=await this.getCodeVersion();t>(await this.isExperimentalMode()?o.EXPERIMENTAL:o.STABLE)||i&&i>=t||(i<l[s.V2_CONFIG]&&r(t,s.V2_CONFIG)&&await this.config.migrate(),i<l[s.V2_PRIVATE_PROFILE]&&r(t,s.V2_PRIVATE_PROFILE)&&await this.view.privateProfile.migrate(),await this.updateCodeVersion(t))}async _applyAddPluginOperation(e,{id:t}){const{name:i,key:n,length:a,fork:s}=e.value.value;await this.members.isModerator(t.key)&&await this.updatePlugin(i,{key:n,length:a,fork:s})}async autobaseApply(e,t){switch(e.value.subtype){case n.SUBTYPE:return this._applyGenesisOperation(e,t);case i.SUBTYPE:return this._applyUpgradeOperation(e,t);case a.SUBTYPE:return this._applyAddPluginOperation(e,t)}}};