about summary refs log tree commit diff
path: root/Tests/LibMatrix.HomeserverEmulator/Services/RoomStore.cs
blob: b4624abab278baf0f44bde2fe1e0cab205399165 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
using System.Collections.Concurrent;
using System.Security.Cryptography;
using LibMatrix.EventTypes;
using LibMatrix.EventTypes.Spec.State;
using LibMatrix.Responses;

namespace LibMatrix.HomeserverEmulator.Services;

public class RoomStore {
    public ConcurrentBag<Room> _rooms = new();
    private Dictionary<string, Room> _roomsById = new();

    private void RebuildIndexes() {
        _roomsById = _rooms.ToDictionary(u => u.RoomId);
    }

    public Room? GetRoomById(string roomId, bool createIfNotExists = false) {
        if (_roomsById.TryGetValue(roomId, out var user)) {
            return user;
        }

        if (!createIfNotExists)
            return null;

        return CreateRoom(new() { });
    }

    public Room CreateRoom(CreateRoomRequest request) {
        var room = new Room {
            RoomId = $"!{Guid.NewGuid().ToString()}"
        };
        if (!string.IsNullOrWhiteSpace(request.Name))
            room.SetStateInternal(new StateEvent() {
                Type = RoomNameEventContent.EventId,
                TypedContent = new RoomNameEventContent() {
                    Name = request.Name
                }
            });

        if (!string.IsNullOrWhiteSpace(request.RoomAliasName))
            room.SetStateInternal(new StateEvent() {
                Type = RoomCanonicalAliasEventContent.EventId,
                TypedContent = new RoomCanonicalAliasEventContent() {
                    Alias = $"#{request.RoomAliasName}:localhost"
                }
            });

        foreach (var stateEvent in request.InitialState ?? []) {
            room.SetStateInternal(stateEvent);
        }

        _rooms.Add(room);
        RebuildIndexes();
        return room;
    }

    public class Room {
        public string RoomId { get; set; }
        public List<StateEventResponse> State { get; set; } = new();
        public Dictionary<string, EventContent> Timeline { get; set; } = new();

        internal StateEventResponse SetStateInternal(StateEvent request) {
            var state = new StateEventResponse() {
                Type = request.Type,
                StateKey = request.StateKey,
                RawContent = request.RawContent,
                EventId = Guid.NewGuid().ToString()
            };
            State.Add(state);
            return state;
        }

        public StateEventResponse AddUser(string userId) {
            return SetStateInternal(new() {
                Type = RoomMemberEventContent.EventId,
                StateKey = userId,
                TypedContent = new RoomMemberEventContent() {
                    Membership = "join"
                }
            });
        }
    }
}