--- /dev/null
+package net.pterodactylus.rhynodge.filters.webpages.epicgames
+
+import com.fasterxml.jackson.databind.JsonNode
+import net.pterodactylus.rhynodge.Filter
+import net.pterodactylus.rhynodge.State
+import net.pterodactylus.rhynodge.states.AbstractState
+import net.pterodactylus.rhynodge.states.JsonState
+import java.time.Instant
+
+class EpicGamesFilter : Filter {
+
+ override fun filter(state: State): State {
+ state as? JsonState ?: throw IllegalArgumentException("state must be a JSON state")
+ return state.jsonNode.at("/data/Catalog/searchStore/elements").map { gameJson: JsonNode ->
+ val title = gameJson.get("title").asText()
+ val imageUrl = gameJson.at("/keyImages/1/url").asText()
+ val startDate = getPromotionalOfferStartDate(gameJson)
+ val endDate = getPromotionalOfferEndDate(gameJson)
+ FreeGame(title, imageUrl, startDate, endDate)
+ }.let { FreeGamesState(it.toSet()) }
+ }
+
+ private fun getPromotionalOfferEndDate(gameJson: JsonNode) = getPromotionalOfferDate(gameJson, "endDate")
+ private fun getPromotionalOfferStartDate(gameJson: JsonNode) = getPromotionalOfferDate(gameJson, "startDate")
+
+ private fun getPromotionalOfferDate(gameJson: JsonNode, date: String) = listOf("promotionalOffers", "upcomingPromotionalOffers")
+ .map { "/promotions/$it/0/promotionalOffers/0/$date" }
+ .map { gameJson.at(it) }
+ .filter { !it.isMissingNode }
+ .map { it.asText() }
+ .map(Instant::parse)
+ .first()
+
+}
+
+data class FreeGame(
+ val title: String,
+ val imageUrl: String,
+ val startDate: Instant,
+ val endDate: Instant
+)
+
+class FreeGamesState(val games: Set<FreeGame>) : AbstractState(true) {
+
+ override fun plainText(): String {
+ TODO("Not yet implemented")
+ }
+
+}