const Promise = require("bluebird");
const MatrixUser = require("../models/users/matrix");
const MatrixRoom = require("../models/rooms/matrix");
/**
* Bridge context.
*
* @property {Object} senders Data models on senders of this event
* @property {MatrixUser} senders.matrix The sender of this event
* @property {?RemoteUser} senders.remote The first linked remote sender: remotes[0]
* @property {RemoteUser[]} senders.remotes The linked remote senders
* @property {Object} targets Data models on targets (e.g. state_key in
* m.room.member) of this event.
* @property {?MatrixUser} targets.matrix The target of this event if applicable.
* @property {?RemoteUser} targets.remote The first linked remote target: remotes[0]
* @property {RemoteUser[]} targets.remotes The linked remote targets
* @property {Object} rooms Data models on rooms concerning this event.
* @property {MatrixRoom} rooms.matrix The room for this event.
* @property {?RemoteRoom} rooms.remote The first linked remote room: remotes[0]
* @property {RemoteRoom[]} rooms.remotes The linked remote rooms for this event
*/
class BridgeContext {
/**
* @param {Object} ctx Event related data
* @param {string} ctx.sender Matrix user ID of the sender.
* @param {string=} ctx.target Matrix user ID of the target.
* @param {string} ctx.room Matrix room ID.
*/
constructor(ctx) {
this._ctx = ctx;
this.senders = {
matrix: new MatrixUser(ctx.sender),
remote: null,
remotes: [],
};
this.targets = {
matrix: ctx.target ? new MatrixUser(ctx.target) : null,
remote: null,
remotes: [],
};
this.rooms = {
matrix: new MatrixRoom(ctx.room),
remote: null,
remotes: [],
};
}
/**
* Returns this instance after its initialization.
*
* @param {RoomBridgeStore} roomStore
* @param {UserBridgeStore} userStore
* @returns {Promise<BridgeContext>}
*/
async get(roomStore, userStore) {
return Promise.try(() => {
return [
roomStore.getLinkedRemoteRooms(this._ctx.room),
userStore.getRemoteUsersFromMatrixId(this._ctx.sender),
(this._ctx.target ?
userStore.getRemoteUsersFromMatrixId(this._ctx.target) :
Promise.resolve([])
),
roomStore.getMatrixRoom(this._ctx.room),
userStore.getMatrixUser(this._ctx.sender)
];
}).spread((remoteRooms, remoteSenders, remoteTargets, mxRoom, mxSender) => {
if (remoteRooms.length) {
this.rooms.remotes = remoteRooms;
this.rooms.remote = remoteRooms[0];
}
if (remoteSenders.length) {
this.senders.remotes = remoteSenders;
this.senders.remote = remoteSenders[0];
}
if (remoteTargets.length) {
this.targets.remotes = remoteTargets;
this.targets.remote = remoteTargets[0];
}
if (mxRoom) {
this.rooms.matrix = mxRoom;
}
if (mxSender) {
this.senders.matrix = mxSender;
}
}).catch(e => {throw wrap(e, Error, "Could not retrieve bridge context");})
.return(this);
}
}
module.exports = BridgeContext;