1 module discord.w.data;
2 
3 import discord.w.types;
4 import discord.w.cache;
5 
6 import std.array;
7 import std.algorithm;
8 import std.typecons;
9 
10 struct GuildUserCache
11 {
12 	Snowflake[2] guildUserID;
13 	Snowflake[] roles;
14 	Nullable!Activity game;
15 	SafeTime joinDate;
16 	PresenceUpdate.Status status;
17 	bool deaf, mute;
18 	string nick;
19 
20 	Role[] resolveRoles() @safe
21 	{
22 		return guild.roles.filter!(a => roles.canFind(a.id)).array;
23 	}
24 
25 	Guild guild() @safe @property
26 	{
27 		return gGuildCache.get(guildUserID[0]);
28 	}
29 
30 	User user() @safe @property
31 	{
32 		return gUserCache.get(guildUserID[1]);
33 	}
34 
35 	string effectiveNick() @safe @property
36 	{
37 		return nick.length ? nick : user.username;
38 	}
39 }
40 
41 struct ChannelUserCache
42 {
43 	Snowflake[2] channelUserID;
44 	SafeTime typing;
45 }
46 
47 struct VoiceStateCache
48 {
49 	VoiceState state;
50 
51 	ref Snowflake[3] id() @property @trusted
52 	{
53 		static assert(is(typeof(VoiceState.tupleof[0]) == Snowflake));
54 		static assert(is(typeof(VoiceState.tupleof[1]) == Snowflake));
55 		static assert(is(typeof(VoiceState.tupleof[2]) == Snowflake));
56 
57 		return (cast(Snowflake*)&state)[0 .. 3];
58 	}
59 }
60 
61 __gshared auto _gUserCache = new SimpleCache!User();
62 __gshared auto _gGuildUserCache = new SimpleCache!(GuildUserCache, "guildUserID")();
63 __gshared auto _gChannelUserCache = new SimpleCache!(ChannelUserCache, "channelUserID")();
64 __gshared auto _gVoiceStateCache = new SimpleCache!VoiceStateCache();
65 __gshared auto _gChannelCache = new SimpleCache!Channel();
66 __gshared auto _gGuildCache = new SimpleCache!Guild();
67 __gshared auto _gMessageCache = new SimpleCache!(Message, "id", 16 * 1024 * 1024)();
68 
69 auto gUserCache() @trusted
70 {
71 	return _gUserCache;
72 }
73 
74 auto gGuildUserCache() @trusted
75 {
76 	return _gGuildUserCache;
77 }
78 
79 auto gChannelUserCache() @trusted
80 {
81 	return _gChannelUserCache;
82 }
83 
84 auto gVoiceStateCache() @trusted
85 {
86 	return _gVoiceStateCache;
87 }
88 
89 auto gChannelCache() @trusted
90 {
91 	return _gChannelCache;
92 }
93 
94 auto gGuildCache() @trusted
95 {
96 	return _gGuildCache;
97 }
98 
99 auto gMessageCache() @trusted
100 {
101 	return _gMessageCache;
102 }
103 
104 Snowflake getGuildByChannel(Snowflake channel) @safe
105 {
106 	return gChannelCache.get(channel).guild_id;
107 }
108 
109 Permissions getUserPermissions(Snowflake guild, Snowflake channel, Snowflake user) @safe
110 {
111 	// TODO: implement channel overwrites
112 
113 	auto guildMember = gGuildUserCache.get([guild, user]);
114 	auto roles = guildMember.resolveRoles;
115 
116 	Permissions ret;
117 	foreach (role; roles)
118 		ret |= cast(Permissions) role.permissions;
119 	return ret;
120 }
121 
122 bool hasPermission(Permissions src, Permissions check) @safe
123 {
124 	if (src & Permissions.ADMINISTRATOR)
125 		return true;
126 	return (src & check) != 0;
127 }