const e=require("ready-resource"),t=require("safety-catch"),i=require("b4a"),o=require("./view"),{ConfigKey:s}=require("./constants"),n=require("../../schema/spec"),a=n.api.hrpc;module.exports=class extends e{static View=o;static ConfigKey=s;static Schemas={Contract:n.contract.hyperschema,Local:n.local.hyperschema,Api:n.api.hyperschema,Config:n.config.hyperschema};constructor(e,i){super(),this.rpc=new a(e),this.view=new o,this.opts=i,this._wantClock=0,this._haveClock=0,this._unwants=new Map,this._gcInterval=setInterval(()=>this._gc(),1e3),this.rpc.onCoreHaveIdentity(this._handleHaveIdentity.bind(this)),this.rpc.onCoreHavePairing(this._handleHavePairing.bind(this)),this.rpc.onCoreHaveLobby(this._handleHaveLobby.bind(this)),this.rpc.onCoreHaveChat(this._handleHaveChat.bind(this)),this.rpc.onCoreHaveMembers(this._handleHaveMembers.bind(this)),this.rpc.onCoreHaveRoomInfo(this._handleHaveRoomInfo.bind(this)),this.rpc.onCoreIdentityReset(this._handleIdentityReset.bind(this)),this.rpc.onCoreIdentityMember(this._handleIdentityMember.bind(this)),this.rpc.onCoreIdentityDevice(this._handleIdentityDevice.bind(this)),this.rpc.onCorePairingReset(this._handlePairingReset.bind(this)),this.rpc.onCoreLobbyReset(this._handleLobbyReset.bind(this)),this.rpc.onCoreLobbyRoom(this._handleLobbyRoom.bind(this)),this.rpc.onCoreChatReset(this._handleChatReset.bind(this)),this.rpc.onCoreRoomInfo(this._handleRoomInfo.bind(this)),this.rpc.onCoreRoomInfoRole(this._handleRoomInfoRole.bind(this)),this.rpc.onCoreRoomInfoDigest(this._handleRoomInfoDigest.bind(this)),this.rpc.onCoreRoomInfoConfig(this._handleRoomInfoConfig.bind(this)),this.rpc.onCoreRoomInfoLastMessage(this._handleRoomInfoLastMessage.bind(this)),this.rpc.onCoreMessageInfo(this._handleMessageInfo.bind(this)),this.rpc.onCoreMessageInfoChat(this._handleMessageInfoChat.bind(this)),this.rpc.onCoreMessageInfoRole(this._handleMessageInfoRole.bind(this)),this.rpc.onCoreMessageInfoMember(this._handleMessageInfoMember.bind(this)),this.rpc.onCoreMessageInfoReactions(this._handleMessageInfoReactions.bind(this)),this.rpc.onCoreMemberListAdd(this._handleMemberListAdd.bind(this)),this.rpc.onCoreMemberListRemove(this._handleMemberListRemove.bind(this)),this.rpc.onCoreMember(this._handleMember.bind(this)),this.rpc.onCoreDevice(this._handleDevice.bind(this)),this.ready().catch(t)}_makeRequest(e){return{header:{timestamp:Date.now()},...e}}_makeWant(e){const t={clock:++this._wantClock,...e};return{want:t,unwant:{clock:t.clock}}}_awaitHave(e,t){return new Promise(i=>{const o=s=>{s===t&&(e.off("have",o),i(t))};e.on("have",o)})}_open(){}_close(){clearInterval(this._gcInterval)}_gc(){this._haveClock<this._wantClock||(this.view.members.maybeGC(),this.view.devices.maybeGC(),this.view.reactions.maybeGC(),this.view.messages.maybeGC(),this.view.rooms.maybeGC())}_handleIdentityReset(e){this.view.identity.onReset(e)}_handleIdentityMember(e){this.view.identity.onMemberChanged(e)}_handleIdentityDevice(e){this.view.identity.onDeviceChanged(e)}_handlePairingReset(e){this.view.pairing.onReset(e)}_handleLobbyReset(e){this.view.lobby.onReset(e)}_handleLobbyRoom(e){this.view.lobby.onRoom(e)}_handleRoomInfo(e){this.view.roomInfo.onAdd(e)}_handleRoomInfoRole(e){const t=i.toString(e.id,"hex");this.view.roomInfo.onRoleChanged({id:t,role:e.role})}_handleRoomInfoDigest(e){const t=i.toString(e.id,"hex");this.view.roomInfo.onDigestChanged({id:t,digest:e.digest})}_handleRoomInfoConfig(e){const t=i.toString(e.id,"hex");this.view.roomInfo.onConfigChanged({id:t,config:e.config})}_handleRoomInfoLastMessage(e){const t=i.toString(e.id,"hex");this.view.roomInfo.onLastMessageChanged({id:t,messageId:e.lastMessage})}_handleMessageInfo(e){this.view.messageInfo.onAdd(e)}_handleMessageInfoChat(e){this.view.messageInfo.onChatChanged(e)}_handleMessageInfoRole(e){this.view.messageInfo.onRoleChanged(e)}_handleMessageInfoMember(e){this.view.messageInfo.onMemberChanged(e)}_handleMessageInfoReactions(e){this.view.messageInfo.onReactionsChanged(e)}_handleChatReset(e){this.view.chat.onReset(e)}_handleMemberListAdd(){}_handleMemberListRemove(){}_handlePairingChanged(){}_handleMessage(e){this.view.messages.add(e)}_handleReactions(e){this.view.reactions.add(e)}_handleMember(e){this.view.members.add(e)}_handleDevice(e){this.view.devices.add(e)}_handleHaveIdentity({clock:e}){this._haveClock=Math.max(this._haveClock,e),this.view.identity.onHave(e)}_handleHavePairing({clock:e}){this._haveClock=Math.max(this._haveClock,e),this.view.pairing.onHave(e)}_handleHaveLobby({clock:e}){this._haveClock=Math.max(this._haveClock,e),this.view.lobby.onHave(e)}_handleHaveRoomInfo({clock:e}){this._haveClock=Math.max(this._haveClock,e),this.view.rooms.onHave(e)}_handleHaveChat({clock:e}){this._haveClock=Math.max(this._haveClock,e),this.view.chat.onHave(e)}_handleHaveMembers({clock:e}){this._haveClock=Math.max(this._haveClock,e),this.view.members.onHave(e)}viewIdentity(){const{want:e,unwant:t}=this._makeWant();return this.view.identity.onWant(e.clock),this.rpc.coreWantIdentity(e),this._unwants.set(e.clock,()=>{this.view.identity.onCancel(e.clock),this.rpc.coreUnwantIdentity(t)}),this._awaitHave(this.view.identity,e.clock)}viewPairing(){const{want:e,unwant:t}=this._makeWant();return this.view.pairing.onWant(e.clock),this.rpc.coreWantPairing(e),this._unwants.set(e.clock,()=>{this.view.pairing.onCancel(e.clock),this.rpc.coreUnwantPairing(t)}),this._awaitHave(this.view.pairing,e.clock)}viewLobby({start:e=0,end:t=0}={}){const{want:i,unwant:o}=this._makeWant({start:e,end:t});return this.view.lobby.onWant(i.clock,e,t),this.rpc.coreWantLobby(i),this._unwants.set(i.clock,()=>{this.view.lobby.onCancel(i.clock),this.rpc.coreUnwantLobby(o)}),this._awaitHave(this.view.lobby,i.clock)}viewChat({roomKey:e,start:t=0,size:i=0,isBottom:o=!1}={}){const{want:s,unwant:n}=this._makeWant({roomKey:e,start:t,size:i,isBottom:o});return this.view.chat.onWant(s.clock,e,t,i,o),this.rpc.coreWantChat(s),this._unwants.set(s.clock,()=>{this.view.chat.onCancel(s.clock),this.rpc.coreUnwantChat(n)}),this._awaitHave(this.view.chat,s.clock)}viewMembers(e,t,i){this.rpc.coreWantMembers(this._makeWant({roomKey:e,offset:t,count:i}))}viewReactions(e,t,i,o){this.rpc.coreWantReactions(this._makeWant({roomKey:e,messageId:t,offset:i,count:o}))}cancel(e){}async boot(){await this.rpc.boot(this._makeRequest(this.opts))}async createRoom(e={}){const t=await this.rpc.coreCreateRoom(this._makeRequest(e));return{roomKey:t.roomKey,roomId:i.toString(t.roomKey,"hex")}}leaveRoom(e){return this.rpc.coreLeaveRoom(this._makeRequest({roomKey:e}))}activateRoom(e){return this.rpc.coreActivateRoom(this._makeRequest({roomKey:e}))}deactivateRoom(e){return this.rpc.coreDeactivateRoom(this._makeRequest({roomKey:e}))}updateRoomConfig(e,t,i){return this.rpc.coreUpdateRoomConfig(this._makeRequest({roomKey:e,key:t,config:i}))}async startPairingRoom(e){return this.rpc.coreStartPairing(this._makeRequest({invitation:e,isIdentity:!1}))}async startPairingIdentity(e){return this.rpc.coreStartPairing(this._makeRequest({invitation:e,isIdentity:!0}))}createRoomInvitation(e,t={}){return this.rpc.coreCreateRoomInvitation(this._makeRequest({roomKey:e,permissions:t,expiration:t.expiration}))}createIdentityInvitation(){return this.rpc.coreCreateIdentityInvitation(this._makeRequest())}acceptJoinRequest(e,t){return this.rpc.coreAcceptJoinRequest(this._makeRequest({roomKey:e,request:t}))}rejectJoinRequest(e,t){return this.rpc.coreRejectJoinRequest(this._makeRequest({roomKey:e,request:t}))}stopPairing(e){return this.rpc.coreStopPairing(this._makeRequest({id:e}))}addChatMessage(e,t){return this.rpc.coreAddChatMessage(this._makeRequest({roomKey:e,message:t}))}editChatMessage(e,t,i){return this.rpc.coreEditChatMessage(this._makeRequest({roomKey:e,id:t,message:i}))}removeChatMessage(e,t){return this.rpc.coreRemoveChatMessage(this._makeRequest({roomKey:e,id:t}))}addChatReaction(e,t,i){return this.rpc.coreAddChatReaction(this._makeRequest({roomKey:e,id:t,reaction:i}))}removeChatReaction(e,t,i){return this.rpc.coreRemoveChatReaction(this._makeRequest({roomKey:e,id:t,reaction:i}))}updateProfile(e){return this.rpc.coreUpdateProfile(this._makeRequest(e))}};