2929
3030import static org .togetherjava .tjbot .db .generated .tables .CakeDays .CAKE_DAYS ;
3131
32+ /**
33+ * Represents a routine for managing cake day celebrations.
34+ * <p>
35+ * This routine handles the assignment and removal of a designated cake day role to guild members
36+ * based on their anniversary of joining the guild.
37+ */
3238public class CakeDayRoutine implements Routine {
3339
3440 private static final Logger logger = LoggerFactory .getLogger (CakeDayRoutine .class );
@@ -39,31 +45,24 @@ public class CakeDayRoutine implements Routine {
3945 private final CakeDayConfig config ;
4046 private final Database database ;
4147
48+ /**
49+ * Constructs a new {@link CakeDayRoutine} instance.
50+ *
51+ * @param config the configuration for cake day routines
52+ * @param database the database for accessing cake day data
53+ */
4254 public CakeDayRoutine (Config config , Database database ) {
4355 this .config = config .getCakeDayConfig ();
4456 this .database = database ;
4557
4658 this .cakeDayRolePredicate = Pattern .compile (this .config .rolePattern ()).asPredicate ();
4759 }
4860
49- /**
50- * Retrieves the schedule of this routine. Called by the core system once during the startup in
51- * order to execute the routine accordingly.
52- * <p>
53- * Changes on the schedule returned by this method afterwards will not be picked up.
54- *
55- * @return the schedule of this routine
56- */
5761 @ Override
5862 public Schedule createSchedule () {
5963 return new Schedule (ScheduleMode .FIXED_RATE , 0 , 1 , TimeUnit .DAYS );
6064 }
6165
62- /**
63- * Triggered by the core system on the schedule defined by {@link #createSchedule()}.
64- *
65- * @param jda the JDA instance the bot is operating with
66- */
6766 @ Override
6867 public void runRoutine (JDA jda ) {
6968 if (getCakeDayCount (this .database ) == 0 ) {
@@ -89,6 +88,14 @@ public void runRoutine(JDA jda) {
8988 jda .getGuilds ().forEach (this ::reassignCakeDayRole );
9089 }
9190
91+ /**
92+ * Reassigns the cake day role for all members of the given guild.
93+ * <p>
94+ * If the cake day role is not found based on the configured pattern, a warning message is
95+ * logged, and no action is taken.
96+ *
97+ * @param guild the guild for which to reassign the cake day role
98+ */
9299 private void reassignCakeDayRole (Guild guild ) {
93100 Role cakeDayRole = getCakeDayRoleFromGuild (guild ).orElse (null );
94101
@@ -103,6 +110,16 @@ private void reassignCakeDayRole(Guild guild) {
103110 .join ();
104111 }
105112
113+ /**
114+ * Asynchronously adds the specified cake day role to guild members who are celebrating their
115+ * cake day today.
116+ * <p>
117+ * The cake day role is added to members who have been in the guild for at least one year.
118+ *
119+ * @param cakeDayRole the cake day role to add to qualifying members
120+ * @param guild the guild in which to add the cake day role to members
121+ * @return a {@link CompletableFuture} representing the asynchronous operation
122+ */
106123 private CompletableFuture <Void > addTodayMembersCakeDayRole (Role cakeDayRole , Guild guild ) {
107124 return CompletableFuture
108125 .runAsync (() -> findCakeDaysTodayFromDatabase ().forEach (cakeDayRecord -> {
@@ -115,26 +132,67 @@ private CompletableFuture<Void> addTodayMembersCakeDayRole(Role cakeDayRole, Gui
115132 }));
116133 }
117134
135+ /**
136+ * Removes the specified cake day role from all members who possess it in the given guild
137+ * asynchronously.
138+ *
139+ * @param cakeDayRole The cake day role to be removed from members.
140+ * @param guild The guild from which to remove the cake day role.
141+ * @return A CompletableFuture representing the asynchronous operation.
142+ */
118143 private CompletableFuture <Void > removeMembersCakeDayRole (Role cakeDayRole , Guild guild ) {
119144 return CompletableFuture .runAsync (() -> guild .findMembersWithRoles (cakeDayRole )
120145 .onSuccess (members -> removeRoleFromMembers (guild , cakeDayRole , members )));
121146 }
122147
148+
149+ /**
150+ * Removes a specified role from a list of members in a guild.
151+ *
152+ * @param guild the guild from which to remove the role from members
153+ * @param role the role to be removed from the members
154+ * @param members the list of members from which the role will be removed
155+ */
123156 private void removeRoleFromMembers (Guild guild , Role role , List <Member > members ) {
124157 members .forEach (member -> {
125158 UserSnowflake snowflake = UserSnowflake .fromId (member .getIdLong ());
126159 guild .removeRoleFromMember (snowflake , role ).complete ();
127160 });
128161 }
129162
163+ /**
164+ * Retrieves the count of cake days from the provided database.
165+ * <p>
166+ * This uses the table <b>cake_days</b> to find the answer.
167+ *
168+ * @param database the database from which to retrieve the count of cake days
169+ * @return the count of cake days stored in the database
170+ */
130171 private int getCakeDayCount (Database database ) {
131172 return database .read (context -> context .fetchCount (CAKE_DAYS ));
132173 }
133174
175+ /**
176+ * Populates cake days for all guilds in the provided JDA instance.
177+ * <p>
178+ * This method iterates through all guilds in the provided JDA instance and populates cake days
179+ * for each guild. It is primarily used for batch populating the <b>cake_days</b> table once it
180+ * is found to be empty.
181+ *
182+ * @param jda the JDA instance containing the guilds to populate cake days for
183+ */
134184 private void populateAllGuildCakeDays (JDA jda ) {
135185 jda .getGuilds ().forEach (this ::batchPopulateGuildCakeDays );
136186 }
137187
188+ /**
189+ * Batch populates guild cake days for the given guild.
190+ * <p>
191+ * Uses a buffer for all the queries it makes and its size is determined by the
192+ * {@code BULK_INSERT_SIZE} option.
193+ *
194+ * @param guild the guild for which to populate cake days
195+ */
138196 private void batchPopulateGuildCakeDays (Guild guild ) {
139197 final List <Query > queriesBuffer = new ArrayList <>();
140198
@@ -155,6 +213,18 @@ private void batchPopulateGuildCakeDays(Guild guild) {
155213 }
156214 }
157215
216+ /**
217+ * Creates a query to insert a member's cake day information into the database.
218+ * <p>
219+ * Primarily used for manually constructing queries for members' cake days which are called from
220+ * {@link CakeDayRoutine#batchPopulateGuildCakeDays(Guild)} and added in a batch to be sent to
221+ * the database.
222+ *
223+ * @param member the member whose cake day information is to be inserted
224+ * @param guildId the ID of the guild to which the member belongs
225+ * @return an Optional containing the query to insert cake day information if the member has a
226+ * join time; empty Optional otherwise
227+ */
158228 private Optional <Query > createMemberCakeDayQuery (Member member , long guildId ) {
159229 if (!member .hasTimeJoined ()) {
160230 return Optional .empty ();
@@ -170,13 +240,24 @@ private Optional<Query> createMemberCakeDayQuery(Member member, long guildId) {
170240 .set (CAKE_DAYS .USER_ID , member .getIdLong ()));
171241 }
172242
243+ /**
244+ * Retrieves the cake day {@link Role} from the specified guild.
245+ *
246+ * @param guild the guild from which to retrieve the cake day role
247+ * @return an optional containing the cake day role if found, otherwise empty
248+ */
173249 private Optional <Role > getCakeDayRoleFromGuild (Guild guild ) {
174250 return guild .getRoles ()
175251 .stream ()
176252 .filter (role -> cakeDayRolePredicate .test (role .getName ()))
177253 .findFirst ();
178254 }
179255
256+ /**
257+ * Finds cake days records for today from the database.
258+ *
259+ * @return a list of {@link CakeDaysRecord} objects representing cake days for today
260+ */
180261 private List <CakeDaysRecord > findCakeDaysTodayFromDatabase () {
181262 String todayMonthDay = OffsetDateTime .now ().format (MONTH_DAY_FORMATTER );
182263
0 commit comments