1 package host.exp.exponent.notifications.schedulers
2 
3 import host.exp.exponent.notifications.helpers.ExpoCronDefinitionBuilder
4 import host.exp.exponent.notifications.managers.SchedulersDatabase
5 import host.exp.exponent.kernel.ExperienceKey
6 import host.exp.exponent.notifications.managers.SchedulersManagerProxy
7 import com.cronutils.parser.CronParser
8 import com.cronutils.model.time.ExecutionTime
9 import android.content.Intent
10 import android.os.SystemClock
11 import com.raizlabs.android.dbflow.annotation.Column
12 import com.raizlabs.android.dbflow.annotation.PrimaryKey
13 import com.raizlabs.android.dbflow.annotation.Table
14 import com.raizlabs.android.dbflow.structure.BaseModel
15 import org.joda.time.DateTime
16 import org.json.JSONException
17 import java.util.*
18 
19 @Table(database = SchedulersDatabase::class)
20 class CalendarSchedulerModel : BaseModel(), SchedulerModel {
21   @Column @PrimaryKey(autoincrement = true) var id = 0
22   @Column override var notificationId = 0
23   @Column(name = "experienceId") var experienceScopeKey: String? = null
24   @Column var isRepeat = false
25   @Column var serializedDetails: String? = null
26   @Column var calendarData: String? = null
27 
28   override val idAsString: String
29     get() = Integer.valueOf(id).toString() + this.javaClass.simpleName
30   override val ownerExperienceKey: ExperienceKey
31     get() = ExperienceKey(experienceScopeKey!!)
32 
canBeReschedulednull33   override fun canBeRescheduled(): Boolean {
34     return isRepeat
35   }
36 
saveAndGetIdnull37   override fun saveAndGetId(): String {
38     save() // get id from database
39     val details = getDetailsMap()
40     details!![SchedulersManagerProxy.SCHEDULER_ID] = idAsString
41     setDetailsFromMap(details)
42     save()
43     return idAsString
44   }
45 
removenull46   override fun remove() {
47     delete()
48   }
49 
50   // elapsedTime
51   override val nextAppearanceTime: Long
52     get() {
53       val cronDefinition = ExpoCronDefinitionBuilder.cronDefinition
54       val parser = CronParser(cronDefinition)
55       val cron = parser.parse(calendarData)
56 
57       val now = DateTime.now()
58       val nextExecution = ExecutionTime.forCron(cron).nextExecution(now)
59       val whenShouldAppear = nextExecution.toDate().time
60       val bootTime = DateTime.now().toDate().time - SystemClock.elapsedRealtime()
61       return whenShouldAppear - bootTime
62     }
63 
shouldBeTriggeredByActionnull64   override fun shouldBeTriggeredByAction(action: String?): Boolean {
65     return triggeringActions.contains(action)
66   }
67 
getDetailsMapnull68   override fun getDetailsMap(): HashMap<String, Any>? {
69     return try {
70       HashMapSerializer.deserialize(serializedDetails)
71     } catch (e: JSONException) {
72       e.printStackTrace()
73       null
74     }
75   }
76 
setDetailsFromMapnull77   override fun setDetailsFromMap(detailsMap: HashMap<String, Any>) {
78     serializedDetails = HashMapSerializer.serialize(detailsMap)
79   }
80 
81   companion object {
82     private val triggeringActions = listOf(
83       null,
84       Intent.ACTION_BOOT_COMPLETED,
85       Intent.ACTION_REBOOT,
86       Intent.ACTION_TIME_CHANGED,
87       Intent.ACTION_TIMEZONE_CHANGED
88     )
89   }
90 }
91