From 72c48794fc16c27950c059d557c56215361186ed Mon Sep 17 00:00:00 2001
From: InsanusMokrassar <ovsyannikov.alexey95@gmail.com>
Date: Sat, 28 Nov 2020 23:05:01 +0600
Subject: [PATCH] add TriggersToPostsRepo

---
 .../publishing/PublishingKeysRegistrar.kt     | 15 +++++++++
 ...ervice.kt => TriggersManagementService.kt} | 21 ++++++++++---
 .../publishing/repos/TriggersToPostsRepo.kt   | 31 +++++++++++++++++++
 .../ktor/client/TriggerSetterClient.kt        |  6 ++--
 .../ktor/server/TriggerSetterConfigurator.kt  |  9 +++---
 5 files changed, 70 insertions(+), 12 deletions(-)
 rename publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/{TriggerSetterService.kt => TriggersManagementService.kt} (60%)
 create mode 100644 publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/repos/TriggersToPostsRepo.kt

diff --git a/publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/PublishingKeysRegistrar.kt b/publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/PublishingKeysRegistrar.kt
index 43a76a66..587ed906 100644
--- a/publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/PublishingKeysRegistrar.kt
+++ b/publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/PublishingKeysRegistrar.kt
@@ -22,6 +22,9 @@ interface WritePublishingRegistrar {
         key: TriggerControlKey,
         postId: PostId
     ): Boolean
+    suspend fun unregisterTriggerForPost(
+        postId: PostId
+    ): Boolean
 }
 
 interface PublishingKeysRegistrar : ReadPublishingRegistrar, WritePublishingRegistrar
@@ -48,5 +51,17 @@ class BusinessPublishingKeysRegistrar(
             }
         }
     }
+
+    override suspend fun unregisterTriggerForPost(
+        postId: PostId
+    ): Boolean = repo.getTriggerControlKeyByPostId(
+        postId
+    ).let { previousKey ->
+        repo.unsetPostTriggerControlKey(postId).also {
+            if (it && previousKey != null) {
+                unregisteredKeysChannel.send(previousKey)
+            }
+        }
+    }
 }
 
diff --git a/publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/TriggerSetterService.kt b/publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/TriggersManagementService.kt
similarity index 60%
rename from publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/TriggerSetterService.kt
rename to publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/TriggersManagementService.kt
index ce700516..4f625dd0 100644
--- a/publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/TriggerSetterService.kt
+++ b/publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/TriggersManagementService.kt
@@ -8,19 +8,32 @@ class TriggerSetterServiceUnknownTriggerIdException(
     "Unknown trigger id $triggerId"
 )
 
-interface TriggerSetterService {
+interface ReadTriggersManagementService {
+    @Throws(TriggerSetterServiceUnknownTriggerIdException::class)
+    suspend fun getTrigger(postId: PostId): TriggerId?
+}
+
+interface WriteTriggersManagementService {
     @Throws(TriggerSetterServiceUnknownTriggerIdException::class)
     suspend fun setTrigger(postId: PostId, triggerId: TriggerId): Boolean
 }
 
-class BusinessTriggerSetterService(
+interface TriggersManagementService : ReadTriggersManagementService, WriteTriggersManagementService
+
+class BusinessTriggersManagementService(
     private val postKeyGenerator: PostKeyGenerator,
-    private val publishingKeyReceiverGetter: PublishingKeyReceiverGetter
-) : TriggerSetterService {
+    private val publishingKeyReceiverGetter: PublishingKeyReceiverGetter,
+    private val keysRegistrar: PublishingKeysRegistrar
+) : TriggersManagementService {
+    override suspend fun getTrigger(postId: PostId): TriggerId? {
+        TODO("Not yet implemented")
+    }
+
     override suspend fun setTrigger(postId: PostId, triggerId: TriggerId): Boolean {
         val publishingKeyReceiver = publishingKeyReceiverGetter(triggerId) ?: throw TriggerSetterServiceUnknownTriggerIdException(triggerId)
         val triggerControlKey = postKeyGenerator(postId, triggerId)
 
+        keysRegistrar.registerTriggerForPost(triggerControlKey, postId)
         publishingKeyReceiver.acceptKey(postId, triggerControlKey)
         return true
     }
diff --git a/publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/repos/TriggersToPostsRepo.kt b/publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/repos/TriggersToPostsRepo.kt
new file mode 100644
index 00000000..0486655f
--- /dev/null
+++ b/publishing/api/src/commonMain/kotlin/dev/inmo/postssystem/core/publishing/repos/TriggersToPostsRepo.kt
@@ -0,0 +1,31 @@
+package dev.inmo.postssystem.core.publishing.repos
+
+import dev.inmo.micro_utils.repos.*
+import dev.inmo.postssystem.core.post.PostId
+import dev.inmo.postssystem.core.publishing.*
+
+interface ReadTriggersToPostsRepo : ReadKeyValueRepo<PostId, TriggerId>
+interface WriteTriggersToPostsRepo : WriteKeyValueRepo<PostId, TriggerId>
+interface TriggersToPostsRepo : KeyValueRepo<PostId, TriggerId>, WriteTriggersToPostsRepo, ReadTriggersToPostsRepo
+
+fun TriggersToPostsRepo(
+    keyValueRepo: KeyValueRepo<PostId, TriggerId>,
+    generator: PostKeyGenerator,
+    writePublishingKeysRegistrar: WritePublishingRegistrar
+): TriggersToPostsRepo = object : TriggersToPostsRepo, KeyValueRepo<PostId, TriggerId> by keyValueRepo {
+    override suspend fun set(toSet: Map<PostId, TriggerId>) {
+        keyValueRepo.set(
+            toSet.filter { (postId, triggerId) ->
+                val publishingKey = generator(postId, triggerId)
+                writePublishingKeysRegistrar.registerTriggerForPost(publishingKey, postId)
+            }
+        )
+    }
+
+    override suspend fun unset(toUnset: List<PostId>) {
+        toUnset.forEach {
+            writePublishingKeysRegistrar.unregisterTriggerForPost(it)
+        }
+        keyValueRepo.unset(toUnset)
+    }
+}
diff --git a/publishing/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/publishing/ktor/client/TriggerSetterClient.kt b/publishing/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/publishing/ktor/client/TriggerSetterClient.kt
index 0cfe3ee1..d874e7c4 100644
--- a/publishing/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/publishing/ktor/client/TriggerSetterClient.kt
+++ b/publishing/ktor/client/src/commonMain/kotlin/com/insanusmokrassar/postssystem/publishing/ktor/client/TriggerSetterClient.kt
@@ -6,14 +6,14 @@ import dev.inmo.micro_utils.ktor.client.UnifiedRequester
 import dev.inmo.micro_utils.ktor.common.buildStandardUrl
 import dev.inmo.postssystem.core.post.PostId
 import dev.inmo.postssystem.core.publishing.TriggerId
-import dev.inmo.postssystem.core.publishing.TriggerSetterService
+import dev.inmo.postssystem.core.publishing.TriggersManagementService
 import kotlinx.serialization.builtins.serializer
 
-class TriggerSetterKtorClient(
+class TriggersManagementKtorClient(
     private val baseUrl: String,
     private val subRoute: String? = triggersRootRoute,
     private val unifiedRequester: UnifiedRequester
-) : TriggerSetterService {
+) : TriggersManagementService {
     private val apiRootUrl = subRoute ?.let { "$baseUrl/$it" } ?: baseUrl
     override suspend fun setTrigger(postId: PostId, triggerId: TriggerId): Boolean = unifiedRequester.unipost(
         buildStandardUrl(
diff --git a/publishing/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/publishing/ktor/server/TriggerSetterConfigurator.kt b/publishing/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/publishing/ktor/server/TriggerSetterConfigurator.kt
index 98abf85e..36e80b49 100644
--- a/publishing/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/publishing/ktor/server/TriggerSetterConfigurator.kt
+++ b/publishing/ktor/server/src/jvmMain/kotlin/com/insanusmokrassar/postssystem/publishing/ktor/server/TriggerSetterConfigurator.kt
@@ -2,7 +2,6 @@ package com.insanusmokrassar.postssystem.publishing.ktor.server
 
 import com.insanusmokrassar.postssystem.publishing.ktor.*
 import dev.inmo.micro_utils.ktor.server.UnifiedRouter
-import dev.inmo.postssystem.core.post.PostId
 import dev.inmo.postssystem.core.publishing.*
 import io.ktor.application.call
 import io.ktor.http.HttpStatusCode
@@ -10,7 +9,7 @@ import io.ktor.response.respond
 import io.ktor.routing.*
 import kotlinx.serialization.builtins.serializer
 
-private inline fun Route.configureTriggerSetter(triggerSetterService: TriggerSetterService, unifiedRouter: UnifiedRouter) {
+private inline fun Route.configureTriggersManagement(triggerSetterService: TriggerSetterService, unifiedRouter: UnifiedRouter) {
     post("$setTriggerSubRoute/{post_id}/{trigger_id}") {
         unifiedRouter.apply {
             val (postId, triggerId) = uniload(TriggerSettingData.serializer())
@@ -30,14 +29,14 @@ private inline fun Route.configureTriggerSetter(triggerSetterService: TriggerSet
     }
 }
 
-fun Route.configureTriggerSetter(
+fun Route.configureTriggersManagement(
     subRoute: String? = triggersRootRoute,
     triggerSetterService: TriggerSetterService,
     unifiedRouter: UnifiedRouter
 ) {
     subRoute ?.also {
         route(it) {
-            configureTriggerSetter(triggerSetterService, unifiedRouter)
+            configureTriggersManagement(triggerSetterService, unifiedRouter)
         }
-    } ?: configureTriggerSetter(triggerSetterService, unifiedRouter)
+    } ?: configureTriggersManagement(triggerSetterService, unifiedRouter)
 }