package expo.modules.rebreakprotection.filter

import org.junit.Assert.assertEquals
import org.junit.Test

/**
 * Verifiziert dass `DomainHasher` byte-genau die gleichen Hashes produziert wie:
 *  - Server (`apps/rebreak/server/utils/domainHash.ts`)
 *  - iOS    (`apps/rebreak/ios/App/RebreakURLFilter/FilterControlProvider.swift`)
 *
 * Fixtures generiert via Node:
 *   const { createHash } = require("node:crypto");
 *   createHash("sha256").update(normalize("bet365.com")).digest().readBigUInt64BE(0);
 *
 * Wenn diese Tests rot werden, ist Cross-Platform-Sync kaputt — der Filter
 * würde Hashes vom Server nicht mehr finden.
 */
class DomainHasherTest {

    private fun u(decimal: String): Long = java.lang.Long.parseUnsignedLong(decimal)

    @Test
    fun `hash bet365_com matches server fixture`() {
        assertEquals(u("16386124564103164180"), DomainHasher.hash("bet365.com"))
    }

    @Test
    fun `hash is case-insensitive`() {
        assertEquals(
            DomainHasher.hash("bet365.com"),
            DomainHasher.hash("BET365.COM")
        )
    }

    @Test
    fun `hash strips https protocol`() {
        assertEquals(
            DomainHasher.hash("bet365.com"),
            DomainHasher.hash("https://bet365.com")
        )
    }

    @Test
    fun `hash strips path and www-prefix`() {
        assertEquals(
            DomainHasher.hash("bet365.com"),
            DomainHasher.hash("https://www.bet365.com/sport/football")
        )
    }

    @Test
    fun `tipico_de matches server fixture`() {
        assertEquals(u("15748628718838809648"), DomainHasher.hash("tipico.de"))
    }

    @Test
    fun `pokerstars_com matches server fixture`() {
        assertEquals(u("10067937357410366326"), DomainHasher.hash("pokerstars.com"))
    }

    @Test
    fun `casino_com matches server fixture`() {
        assertEquals(u("6264962142342037058"), DomainHasher.hash("casino.com"))
    }

    @Test
    fun `evil subdomain has different hash than parent`() {
        // Subdomain-Match passiert in DnsFilter, nicht im Hasher.
        // Hier nur prüfen dass evil.bet365.com !== bet365.com:
        val parent = DomainHasher.hash("bet365.com")
        val sub = DomainHasher.hash("evil.bet365.com")
        assert(parent != sub)
        assertEquals(u("3035823198435943299"), sub)
    }

    @Test
    fun `whitespace is trimmed`() {
        assertEquals(
            DomainHasher.hash("bet365.com"),
            DomainHasher.hash("   bet365.com   ")
        )
    }

    @Test
    fun `non-blocked domain has its own hash`() {
        assertEquals(u("9120123751810482011"), DomainHasher.hash("rebreak.org"))
        assertEquals(u("15333025010904606490"), DomainHasher.hash("google.com"))
    }
}
