package app.vipergearlab.tactical /** * Trial blocks for the Android build. Wire [evaluate] from the activity. * Web and the Windows exe already run the same five blocks. */ data class BlockReport(val id: String, val status: String, val detail: String) object TrialBlocks { const val TRIAL_DAYS = 10 const val VERIFY_MS = 6L * 60L * 60L * 1000L fun evaluate( now: Long, storedSeal: String?, currentSeal: String?, startedAt: Long?, lastSeenAt: Long?, master: Boolean, gumroadOk: Boolean?, ): List { val seal = when { storedSeal.isNullOrBlank() || currentSeal.isNullOrBlank() -> BlockReport("seal", "open", "Seal not anchored yet.") storedSeal != currentSeal -> BlockReport("seal", "fail", "Host seal does not match the anchor.") else -> BlockReport("seal", "pass", "Anchor matches this host.") } val clock = when { lastSeenAt != null && now + 120_000 < lastSeenAt -> BlockReport("clock", "fail", "Clock moved backwards.") startedAt == null -> BlockReport("clock", "open", "Trial not started.") now >= startedAt + TRIAL_DAYS * 86_400_000L && !master -> BlockReport("clock", "fail", "Trial window closed.") else -> BlockReport("clock", "pass", "Window open or license holds.") } val gumroad = when (gumroadOk) { null -> BlockReport("gumroad", "open", "Product id not set.") true -> BlockReport("gumroad", "pass", "Gumroad license holds.") false -> BlockReport("gumroad", "fail", "Gumroad rejected the key.") } val gate = when { seal.status == "fail" -> BlockReport("gate", "fail", "Read-only.") clock.status == "fail" -> BlockReport("gate", "fail", "Read-only telemetry.") else -> BlockReport("gate", "pass", if (master) "Licensed." else "Trial command.") } return listOf(seal, clock, gumroad, gate) } }