/*
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package com.runicgateway.app.core.push

import kotlinx.serialization.json.Json
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test

/**
 * Parsing tests for the content-free push tickle over ntfy's SSE envelope
 * (PLAN.md §11). A `message` frame yields `{ stream, ref }`; lifecycle frames and
 * malformed bodies are dropped (never thrown, §7).
 */
class PushTickleTest {

    private val json = Json { ignoreUnknownKeys = true }

    @Test fun parsesMessageFrame() {
        // ntfy wraps our POSTed body in { event:"message", message:"<our json>" }.
        val data = """{"id":"x","time":1,"event":"message","topic":"up1","message":"{\"stream\":\"vendor.sale\",\"ref\":\"0x40001\"}"}"""
        val tickle = parseNtfyTickle(json, data)
        assertEquals(PushTickle("vendor.sale", "0x40001"), tickle)
    }

    @Test fun parsesMessageWithoutRef() {
        val data = """{"event":"message","message":"{\"stream\":\"server.status\"}"}"""
        val tickle = parseNtfyTickle(json, data)
        assertEquals("server.status", tickle?.stream)
        assertNull(tickle?.ref)
    }

    @Test fun dropsOpenAndKeepaliveFrames() {
        assertNull(parseNtfyTickle(json, """{"event":"open","topic":"up1"}"""))
        assertNull(parseNtfyTickle(json, """{"event":"keepalive","topic":"up1"}"""))
    }

    @Test fun dropsMalformedOrEmpty() {
        assertNull(parseNtfyTickle(json, ""))
        assertNull(parseNtfyTickle(json, ": keepalive comment"))
        assertNull(parseNtfyTickle(json, "not json"))
        // A message whose inner body isn't our shape → no stream → dropped.
        assertNull(parseNtfyTickle(json, """{"event":"message","message":"{}"}"""))
        assertNull(parseNtfyTickle(json, """{"event":"message","message":"garbage"}"""))
    }

    @Test fun decodeTickleRejectsBlankStream() {
        assertNull(decodeTickle(json, """{"stream":"","ref":"x"}"""))
        assertEquals(PushTickle("news.post"), decodeTickle(json, """{"stream":"news.post"}"""))
    }
}
