1 package host.exp.exponent.notifications.managers
2 
3 import android.content.Context
4 import com.raizlabs.android.dbflow.sql.language.SQLite
5 import expo.modules.core.interfaces.Function
6 import host.exp.exponent.kernel.ExperienceKey
7 import host.exp.exponent.notifications.exceptions.UnableToScheduleException
8 import host.exp.exponent.notifications.schedulers.*
9 
10 internal class SchedulerManagerImpl(private val applicationContext: Context) : SchedulersManager {
11   private var fetchedFromDB = false
12   private val schedulersMap = mutableMapOf<String, Scheduler>()
13 
triggerAllnull14   override fun triggerAll(action: String?) {
15     fetchSchedulersMap()
16 
17     cancelAlreadyScheduled(null)
18 
19     val unsuccessful = mutableListOf<String>()
20     for ((key, value) in schedulersMap) {
21       try {
22         value.schedule(action)
23       } catch (e: UnableToScheduleException) {
24         unsuccessful.add(key)
25       }
26     }
27 
28     for (key in unsuccessful) {
29       removeScheduler(key)
30     }
31   }
32 
removeAllnull33   override fun removeAll(experienceKey: ExperienceKey?) {
34     fetchSchedulersMap()
35 
36     cancelAlreadyScheduled(experienceKey)
37 
38     val toRemove = mutableListOf<String>()
39     for ((key, value) in schedulersMap) {
40       if (experienceKey == null || value.ownerExperienceKey == experienceKey) {
41         value.remove()
42         toRemove.add(key)
43       }
44     }
45 
46     for (key in toRemove) {
47       schedulersMap.remove(key)
48     }
49   }
50 
cancelAlreadySchedulednull51   override fun cancelAlreadyScheduled(experienceKey: ExperienceKey?) {
52     fetchSchedulersMap()
53 
54     for (scheduler in schedulersMap.values) {
55       if (experienceKey == null || scheduler.ownerExperienceKey == experienceKey) {
56         scheduler.cancel()
57       }
58     }
59   }
60 
rescheduleOrDeletenull61   override fun rescheduleOrDelete(id: String?) {
62     fetchSchedulersMap()
63 
64     val scheduler = schedulersMap[id] ?: return
65     if (!scheduler.canBeRescheduled()) {
66       removeScheduler(id)
67     } else {
68       try {
69         scheduler.schedule(null)
70       } catch (e: UnableToScheduleException) {
71         removeScheduler(id)
72       }
73     }
74   }
75 
removeSchedulernull76   override fun removeScheduler(id: String?) {
77     fetchSchedulersMap()
78 
79     schedulersMap.remove(id)?.apply {
80       cancel()
81       remove()
82     }
83   }
84 
addSchedulernull85   override fun addScheduler(scheduler: Scheduler, handler: Function<String, Boolean>) {
86     fetchSchedulersMap()
87 
88     scheduler.setApplicationContext(applicationContext)
89 
90     val id = scheduler.saveAndGetId()
91     schedulersMap[id] = scheduler
92     val idToApply = try {
93       scheduler.schedule(null)
94       id
95     } catch (e: UnableToScheduleException) {
96       removeScheduler(id)
97       null
98     }
99 
100     handler.apply(idToApply)
101   }
102 
fetchSchedulersMapnull103   private fun fetchSchedulersMap() {
104     if (!fetchedFromDB) {
105       fetchedFromDB = true
106 
107       val calendarSchedulers: List<SchedulerModel> = SQLite.select().from(CalendarSchedulerModel::class.java).queryList()
108       val intervalSchedulers: List<SchedulerModel> = SQLite.select().from(IntervalSchedulerModel::class.java).queryList()
109       for (schedulerModel in calendarSchedulers + intervalSchedulers) {
110         val scheduler = SchedulerImpl(schedulerModel)
111         schedulersMap[scheduler.idAsString] = scheduler
112       }
113 
114       for (scheduler in schedulersMap.values) {
115         scheduler.setApplicationContext(applicationContext)
116       }
117     }
118   }
119 }
120