const{Transform:e,pipeline:t}=require("streamx"),i=require("compact-encoding"),a=require("b4a"),{ConfigSchema:s}=require("@holepunchto/keet-core-schemas"),{UpdateConfigOperationV1:n,UpdateConfigOperationV2:o}=s.Operations,{CONFIG:r,VALIDATION:c,FEATURES:h,GENERIC_EVENTS:u,isFeatureSupported:E}=require("@holepunchto/keet-core-api");module.exports=class{static Operations=new Set([n.TYPE,o.TYPE]);constructor(e){this.view=e,this.chat=null,this.members=null,this.config=null,this.configV2=null}initialize(){this.chat=this.view.chat,this.members=this.view.members,this.chat=this.view.chat,this.config=this.view.collections.config,this.configV2=this.view.bee}async get(e){const t=await this.configV2.get(e,s.Encoding);return s.getValue(t)}async getAll(e={}){const t={};for await(const{key:i,value:a}of this.createReadStream(e))t[i]=a;return t}async put(e,t){await this.configV2.put(e,t,s.Encoding)}createReadStream(i={}){const a=this.configV2.createReadStream(i,s.Encoding);return t(a,new e({transform(e,t){t(null,{key:e.key,value:s.getValue(e)})}}))}async getConfig(){const e=await this.config.get(r.V1_CONFIG_KEY);return{...e?e.value:{},...await this.getAll()}}async isBroadcastRoom(){const e=await this.getConfig();return!!e&&"1"===e.roomType}async isDisableMembershipEvents(){return 1===await this.get(r.DISABLE_MEMBERSHIP_EVENTS)}async deletePinnedMessageIfExists(e){const t=await this.get(r.PINNED_MESSAGES)||[],i=t.findIndex(t=>a.equals(t.key,e.key)&&t.seq===e.seq);-1!==i&&(t.splice(i,1),await this.put(r.PINNED_MESSAGES,s.encodeValue(r.PINNED_MESSAGES,t)))}async _validate(e,t){const i=s.decodeValue(e,t);switch(e){case r.PINNED_MESSAGES:return!await this.view.isUnsupportedFeature(h.PINNED_MESSAGES)&&(await Promise.all([this._pinLimitNotExceeded(e,i),this._pinnedMessageExists(e,i)])).every(e=>!0===e);case r.DISABLE_MEMBERSHIP_EVENTS:return await this.view.isFeatureSupported(h.DISABLE_MEMBERSHIP_EVENTS);default:return!0}}_pinLimitNotExceeded(e,t){return t.length<=c.PINNED_MESSAGES_LIMIT}async _pinnedMessageExists(e,t){const i=t.length?t[t.length-1]:null;return!i||await this.chat.messageExists(i)}async _maybeTrackChange({id:e,timestamp:t,from:i,to:a}){await this.view.isFeatureSupported(h.ROOM_RENAME_EVENT)&&null!==i&&i!==a&&await this.chat.addMessage({id:e,timestamp:t,event:{type:u.ROOM_TITLE_CHANGED,value:{from:i,to:a}}})}async _applyUpdateConfigOperationV1(e,{id:t}){const{key:a,value:s}=e.value;if(!await this.members.isModerator(t.key))return;const n=await this.view.internal.getCodeVersion();if(E(n,h.V2_CONFIG))return s?this.put(a,i.encode(i.string,s)):this.configV2.del(a);const o=await this.getConfig();s?o[a]=s:delete o[a],await this.config.update(r.V1_CONFIG_KEY,o,{upsert:!0})}async _applyUpdateConfigOperationV2(e,t){const{id:i}=t,{key:a,value:n}=e.value;if(await this.members.isModerator(i.key)&&await this._validate(a,n)){if(a===r.ROOM_TITLE){const e=await this.get(a),i=s.decodeValue(a,n);await this._maybeTrackChange({...t,from:e,to:i})}await this.put(a,n)}}autobaseApply(e,t){switch(e.type){case n.TYPE:return this._applyUpdateConfigOperationV1(e,t);case o.TYPE:return this._applyUpdateConfigOperationV2(e,t)}}async migrate(){const e=await this.config.get(r.V1_CONFIG_KEY);if(e&&e.value)for await(const t of Object.keys(e.value)){const a=e.value[t];await this.put(t,i.encode(i.string,a))}}};