Move SSD detection policy to typed Kotlin

ober

a0156a8bf512e78dc2b460fc53d2648cd6ecdcd0

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index ca26551..5d8e24f 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -3877,7 +3877,9 @@
                 pageNumberText sessionIdFromUuid nullableLowercaseOrEmpty
                 selectModeStatus selectionResultStatus detectStartStatus
                 detectorSourceWithTruth detectionTruthNote detectionOcrNote
-                detectionLearnedNote shouldApplyLearnedGuesses
+                detectionLearnedNote shouldLoadLocalTruth
+                shouldUseExistingTruth shouldApplyExistingTruth
+                shouldApplyLearnedGuesses shouldMergeRemoteTruth
                 reviewPrimaryColor reviewWhiteColor reviewLabelTextColor
                 reviewLabelBackgroundColor reviewCanvasBackgroundColor
                 reviewAccentColor reviewModeColor reviewDarkTextColor
@@ -4326,8 +4328,19 @@
                 (int32->string learnedGuesses)
                 " learned guesses"))
             ""))
+        (def (shouldLoadLocalTruth (forceDetect : Bool)) : Bool
+          (not forceDetect))
+        (def (shouldUseExistingTruth (existingTruthGroupCount : Int32)
+                                     (forceDetect : Bool)) : Bool
+          (and (> existingTruthGroupCount (int32 0))
+               (not forceDetect)))
+        (def (shouldApplyExistingTruth (existingTruthGroupCount : Int32)) : Bool
+          (> existingTruthGroupCount (int32 0)))
         (def (shouldApplyLearnedGuesses (existingTruthGroupCount : Int32)) : Bool
           (= existingTruthGroupCount (int32 0)))
+        (def (shouldMergeRemoteTruth (hasExistingTruth : Bool)
+                                     (forceDetect : Bool)) : Bool
+          (and (not hasExistingTruth) (not forceDetect)))
         (def (reviewPrimaryColor) : Int32
           (androidColorRgb (int32 37) (int32 99) (int32 235)))
         (def (reviewWhiteColor) : Int32
@@ -5880,7 +5893,7 @@
        "                    ssdArea = null"
        "                )"
        ""
-       "                val localTruth = if (forceDetect) null else truthStore.loadTruth(session)"
+       "                val localTruth = if (shouldLoadLocalTruth(forceDetect)) truthStore.loadTruth(session) else null"
 	       "                val localGroupCount = nullableTruthGroupCount(localTruth)"
 	       "                if (localGroupCount >= FAST_TRUTH_GROUP_THRESHOLD) {"
 	       "                    truthStore.applyTruth(session)"
@@ -5906,7 +5919,7 @@
        "                var detectorNote = \"\""
        "                var detectorSource = \"unknown\""
        ""
-	       "                if (existingTruth != null && existingTruthGroupCount > 0 && !forceDetect) {"
+	       "                if (existingTruth != null && shouldUseExistingTruth(existingTruthGroupCount, forceDetect)) {"
 	       "                    detectorSource = \"local-truth\""
 	       "                    session.ssdArea = truthSsdAreaRect(existingTruth)"
 	       "                    truthStore.applyTruth(session)"
@@ -5927,7 +5940,7 @@
        "                    }"
        "                    ssdSessionAddDetectedCellsInsideArea(session, detectedCells)"
        "                    session.groups.addAll(initialGroupsLimited(session.cells, 120))"
-       "                    if (existingTruth != null && existingTruthGroupCount > 0) {"
+       "                    if (existingTruth != null && shouldApplyExistingTruth(existingTruthGroupCount)) {"
        "                        truthStore.applyTruth(session)"
        "                        ssdSessionPruneGroupsOutsideSsdArea(session)"
        "                    }"
@@ -5948,7 +5961,7 @@
        "                    val learnedNote = detectionLearnedNote(learnedGuesses)"
        "                    setStatus(sessionCountsStatus(session, detectorNote + truthNote + ocrNote + learnedNote))"
        "                    logDetectResult(\"page-load\", session, detectorSource, learnedGuesses, ocrGuesses)"
-       "                    if (existingTruth == null && !forceDetect) mergeRemoteTruthAsync(session, expectedGeneration, uri, expectedPageIndex)"
+       "                    if (shouldMergeRemoteTruth(existingTruth != null, forceDetect)) mergeRemoteTruthAsync(session, expectedGeneration, uri, expectedPageIndex)"
        "                }"
        "            } catch (error: Exception) {"
        "                runOnUiThread {"