package com.futo.platformplayer

/*
import com.futo.platformplayer.mdns.DnsOpcode
import com.futo.platformplayer.mdns.DnsPacket
import com.futo.platformplayer.mdns.DnsPacketHeader
import com.futo.platformplayer.mdns.DnsQuestion
import com.futo.platformplayer.mdns.DnsReader
import com.futo.platformplayer.mdns.DnsResponseCode
import com.futo.platformplayer.mdns.DnsWriter
import com.futo.platformplayer.mdns.QueryResponse
import com.futo.platformplayer.mdns.QuestionClass
import com.futo.platformplayer.mdns.QuestionType
import com.futo.platformplayer.mdns.ResourceRecordClass
import com.futo.platformplayer.mdns.ResourceRecordType
*/
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertTrue
import java.io.ByteArrayOutputStream
import java.net.InetAddress
import kotlin.test.Test
import kotlin.test.assertContentEquals


//TODO: Update tests.
class MdnsTests {
/*
    @Test
    fun `BasicOperation`() {
        val expectedData = byteArrayOf(
            0x00, 0x01,
            0x00, 0x00, 0x00, 0x02,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
            0x00, 0x01,
            0x00, 0x00, 0x00, 0x02,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
        )

        val writer = DnsWriter()
        writer.write(1.toUShort())
        writer.write(2.toUInt())
        writer.write(3.toULong())
        writer.write(1.toShort())
        writer.write(2)
        writer.write(3L)

        assertContentEquals(expectedData, writer.toByteArray())
    }

    @Test
    fun `DnsQuestionFormat`() {
        val expectedBytes = ubyteArrayOf(
            0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x08u, 0x5fu, 0x61u, 0x69u, 0x72u, 0x70u, 0x6cu, 0x61u, 0x79u, 0x04u, 0x5fu, 0x74u, 0x63u, 0x70u, 0x05u, 0x6cu, 0x6fu, 0x63u, 0x61u, 0x6cu, 0x00u, 0x00u, 0x0cu, 0x00u, 0x01u
        ).asByteArray()

        val writer = DnsWriter()
        writer.writePacket(
            header = DnsPacketHeader(
                identifier = 0.toUShort(),
                queryResponse = QueryResponse.Query.value.toInt(),
                opcode = DnsOpcode.StandardQuery.value.toInt(),
                authoritativeAnswer = false,
                truncated = false,
                recursionDesired = false,
                recursionAvailable = false,
                answerAuthenticated = false,
                nonAuthenticatedData = false,
                responseCode = DnsResponseCode.NoError
            ),
            questionCount = 1,
            questionWriter = { w, _ ->
                w.write(DnsQuestion(
                    name = "_airplay._tcp.local",
                    type = QuestionType.PTR.value.toInt(),
                    clazz = QuestionClass.IN.value.toInt(),
                    queryUnicast = false
                ))
            }
        )

        assertContentEquals(expectedBytes, writer.toByteArray())
    }

    @Test
    fun `BeyondTests`() {
        val data = byteArrayOf(
            0x00, 0x01,
            0x00, 0x00, 0x00, 0x02,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
            0x00, 0x01,
            0x00, 0x00, 0x00, 0x02,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
        )

        val reader = DnsReader(data)
        assertEquals(1, reader.readInt16())
        assertEquals(2, reader.readInt32())
        assertEquals(3L, reader.readInt64())
        assertEquals(1.toUShort(), reader.readUInt16())
        assertEquals(2.toUInt(), reader.readUInt32())
        assertEquals(3.toULong(), reader.readUInt64())
    }

    @Test
    fun `ParseDnsPrinter`() {
        val data = ubyteArrayOf(
            0x00u, 0x00u,
            0x84u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x06u, 0x04u, 0x5fu, 0x69u, 0x70u, 0x70u, 0x04u,
            0x5fu, 0x74u, 0x63u, 0x70u, 0x05u, 0x6cu, 0x6fu, 0x63u, 0x61u, 0x6cu, 0x00u, 0x00u, 0x0cu, 0x00u, 0x01u, 0x00u,
            0x00u, 0x11u, 0x94u, 0x00u, 0x1eu, 0x1bu, 0x42u, 0x72u, 0x6fu, 0x74u, 0x68u, 0x65u, 0x72u, 0x20u, 0x44u, 0x43u,
            0x50u, 0x2du, 0x4cu, 0x33u, 0x35u, 0x35u, 0x30u, 0x43u, 0x44u, 0x57u, 0x20u, 0x73u, 0x65u, 0x72u, 0x69u, 0x65u,
            0x73u, 0xc0u, 0x0cu, 0xc0u, 0x27u, 0x00u, 0x10u, 0x80u, 0x01u, 0x00u, 0x00u, 0x11u, 0x94u, 0x02u, 0x53u, 0x09u,
            0x74u, 0x78u, 0x74u, 0x76u, 0x65u, 0x72u, 0x73u, 0x3du, 0x31u, 0x08u, 0x71u, 0x74u, 0x6fu, 0x74u, 0x61u, 0x6cu,
            0x3du, 0x31u, 0x42u, 0x70u, 0x64u, 0x6cu, 0x3du, 0x61u, 0x70u, 0x70u, 0x6cu, 0x69u, 0x63u, 0x61u, 0x74u, 0x69u,
            0x6fu, 0x6eu, 0x2fu, 0x6fu, 0x63u, 0x74u, 0x65u, 0x74u, 0x2du, 0x73u, 0x74u, 0x72u, 0x65u, 0x61u, 0x6du, 0x2cu,
            0x69u, 0x6du, 0x61u, 0x67u, 0x65u, 0x2fu, 0x75u, 0x72u, 0x66u, 0x2cu, 0x69u, 0x6du, 0x61u, 0x67u, 0x65u, 0x2fu,
            0x6au, 0x70u, 0x65u, 0x67u, 0x2cu, 0x69u, 0x6du, 0x61u, 0x67u, 0x65u, 0x2fu, 0x70u, 0x77u, 0x67u, 0x2du, 0x72u,
            0x61u, 0x73u, 0x74u, 0x65u, 0x72u, 0x0cu, 0x72u, 0x70u, 0x3du, 0x69u, 0x70u, 0x70u, 0x2fu, 0x70u, 0x72u, 0x69u,
            0x6eu, 0x74u, 0x05u, 0x6eu, 0x6fu, 0x74u, 0x65u, 0x3du, 0x1eu, 0x74u, 0x79u, 0x3du, 0x42u, 0x72u, 0x6fu, 0x74u,
            0x68u, 0x65u, 0x72u, 0x20u, 0x44u, 0x43u, 0x50u, 0x2du, 0x4cu, 0x33u, 0x35u, 0x35u, 0x30u, 0x43u, 0x44u, 0x57u,
            0x20u, 0x73u, 0x65u, 0x72u, 0x69u, 0x65u, 0x73u, 0x25u, 0x70u, 0x72u, 0x6fu, 0x64u, 0x75u, 0x63u, 0x74u, 0x3du,
            0x28u, 0x42u, 0x72u, 0x6fu, 0x74u, 0x68u, 0x65u, 0x72u, 0x20u, 0x44u, 0x43u, 0x50u, 0x2du, 0x4cu, 0x33u, 0x35u,
            0x35u, 0x30u, 0x43u, 0x44u, 0x57u, 0x20u, 0x73u, 0x65u, 0x72u, 0x69u, 0x65u, 0x73u, 0x29u, 0x3cu, 0x61u, 0x64u,
            0x6du, 0x69u, 0x6eu, 0x75u, 0x72u, 0x6cu, 0x3du, 0x68u, 0x74u, 0x74u, 0x70u, 0x3au, 0x2fu, 0x2fu, 0x42u, 0x52u,
            0x57u, 0x31u, 0x30u, 0x35u, 0x42u, 0x41u, 0x44u, 0x34u, 0x41u, 0x31u, 0x35u, 0x37u, 0x30u, 0x2eu, 0x6cu, 0x6fu,
            0x63u, 0x61u, 0x6cu, 0x2eu, 0x2fu, 0x6eu, 0x65u, 0x74u, 0x2fu, 0x6eu, 0x65u, 0x74u, 0x2fu, 0x61u, 0x69u, 0x72u,
            0x70u, 0x72u, 0x69u, 0x6eu, 0x74u, 0x2eu, 0x68u, 0x74u, 0x6du, 0x6cu, 0x0bu, 0x70u, 0x72u, 0x69u, 0x6fu, 0x72u,
            0x69u, 0x74u, 0x79u, 0x3du, 0x32u, 0x35u, 0x0fu, 0x75u, 0x73u, 0x62u, 0x5fu, 0x4du, 0x46u, 0x47u, 0x3du, 0x42u,
            0x72u, 0x6fu, 0x74u, 0x68u, 0x65u, 0x72u, 0x1bu, 0x75u, 0x73u, 0x62u, 0x5fu, 0x4du, 0x44u, 0x4cu, 0x3du, 0x44u,
            0x43u, 0x50u, 0x2du, 0x4cu, 0x33u, 0x35u, 0x35u, 0x30u, 0x43u, 0x44u, 0x57u, 0x20u, 0x73u, 0x65u, 0x72u, 0x69u,
            0x65u, 0x73u, 0x19u, 0x75u, 0x73u, 0x62u, 0x5fu, 0x43u, 0x4du, 0x44u, 0x3du, 0x50u, 0x4au, 0x4cu, 0x2cu, 0x50u,
            0x43u, 0x4cu, 0x2cu, 0x50u, 0x43u, 0x4cu, 0x58u, 0x4cu, 0x2cu, 0x55u, 0x52u, 0x46u, 0x07u, 0x43u, 0x6fu, 0x6cu,
            0x6fu, 0x72u, 0x3du, 0x54u, 0x08u, 0x43u, 0x6fu, 0x70u, 0x69u, 0x65u, 0x73u, 0x3du, 0x54u, 0x08u, 0x44u, 0x75u,
            0x70u, 0x6cu, 0x65u, 0x78u, 0x3du, 0x54u, 0x05u, 0x46u, 0x61u, 0x78u, 0x3du, 0x46u, 0x06u, 0x53u, 0x63u, 0x61u,
            0x6eu, 0x3du, 0x54u, 0x0du, 0x50u, 0x61u, 0x70u, 0x65u, 0x72u, 0x43u, 0x75u, 0x73u, 0x74u, 0x6fu, 0x6du, 0x3du,
            0x54u, 0x08u, 0x42u, 0x69u, 0x6eu, 0x61u, 0x72u, 0x79u, 0x3du, 0x54u, 0x0du, 0x54u, 0x72u, 0x61u, 0x6eu, 0x73u,
            0x70u, 0x61u, 0x72u, 0x65u, 0x6eu, 0x74u, 0x3du, 0x54u, 0x06u, 0x54u, 0x42u, 0x43u, 0x50u, 0x3du, 0x46u, 0x3eu,
            0x55u, 0x52u, 0x46u, 0x3du, 0x53u, 0x52u, 0x47u, 0x42u, 0x32u, 0x34u, 0x2cu, 0x57u, 0x38u, 0x2cu, 0x43u, 0x50u,
            0x31u, 0x2cu, 0x49u, 0x53u, 0x34u, 0x2du, 0x31u, 0x2cu, 0x4du, 0x54u, 0x31u, 0x2du, 0x33u, 0x2du, 0x34u, 0x2du,
            0x35u, 0x2du, 0x38u, 0x2du, 0x31u, 0x31u, 0x2cu, 0x4fu, 0x42u, 0x31u, 0x30u, 0x2cu, 0x50u, 0x51u, 0x34u, 0x2cu,
            0x52u, 0x53u, 0x36u, 0x30u, 0x30u, 0x2cu, 0x56u, 0x31u, 0x2eu, 0x34u, 0x2cu, 0x44u, 0x4du, 0x31u, 0x25u, 0x6bu,
            0x69u, 0x6eu, 0x64u, 0x3du, 0x64u, 0x6fu, 0x63u, 0x75u, 0x6du, 0x65u, 0x6eu, 0x74u, 0x2cu, 0x65u, 0x6eu, 0x76u,
            0x65u, 0x6cu, 0x6fu, 0x70u, 0x65u, 0x2cu, 0x6cu, 0x61u, 0x62u, 0x65u, 0x6cu, 0x2cu, 0x70u, 0x6fu, 0x73u, 0x74u,
            0x63u, 0x61u, 0x72u, 0x64u, 0x11u, 0x50u, 0x61u, 0x70u, 0x65u, 0x72u, 0x4du, 0x61u, 0x78u, 0x3du, 0x6cu, 0x65u,
            0x67u, 0x61u, 0x6cu, 0x2du, 0x41u, 0x34u, 0x29u, 0x55u, 0x55u, 0x49u, 0x44u, 0x3du, 0x65u, 0x33u, 0x32u, 0x34u,
            0x38u, 0x30u, 0x30u, 0x30u, 0x2du, 0x38u, 0x30u, 0x63u, 0x65u, 0x2du, 0x31u, 0x31u, 0x64u, 0x62u, 0x2du, 0x38u,
            0x30u, 0x30u, 0x30u, 0x2du, 0x33u, 0x63u, 0x32u, 0x61u, 0x66u, 0x34u, 0x61u, 0x61u, 0x63u, 0x30u, 0x61u, 0x34u,
            0x0cu, 0x70u, 0x72u, 0x69u, 0x6eu, 0x74u, 0x5fu, 0x77u, 0x66u, 0x64u, 0x73u, 0x3du, 0x54u, 0x14u, 0x6du, 0x6fu,
            0x70u, 0x72u, 0x69u, 0x61u, 0x2du, 0x63u, 0x65u, 0x72u, 0x74u, 0x69u, 0x66u, 0x69u, 0x65u, 0x64u, 0x3du, 0x31u,
            0x2eu, 0x33u, 0x0fu, 0x42u, 0x52u, 0x57u, 0x31u, 0x30u, 0x35u, 0x42u, 0x41u, 0x44u, 0x34u, 0x41u, 0x31u, 0x35u,
            0x37u, 0x30u, 0xc0u, 0x16u, 0x00u, 0x01u, 0x80u, 0x01u, 0x00u, 0x00u, 0x00u, 0x78u, 0x00u, 0x04u, 0xc0u, 0xa8u,
            0x01u, 0xc5u, 0xc2u, 0xa4u, 0x00u, 0x1cu, 0x80u, 0x01u, 0x00u, 0x00u, 0x00u, 0x78u, 0x00u, 0x10u, 0xfeu, 0x80u,
            0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x12u, 0x5bu, 0xadu, 0xffu, 0xfeu, 0x4au, 0x15u, 0x70u, 0xc0u, 0x27u,
            0x00u, 0x21u, 0x80u, 0x01u, 0x00u, 0x00u, 0x00u, 0x78u, 0x00u, 0x08u, 0x00u, 0x00u, 0x00u, 0x00u, 0x02u, 0x77u,
            0xc2u, 0xa4u, 0xc0u, 0x27u, 0x00u, 0x2fu, 0x80u, 0x01u, 0x00u, 0x00u, 0x11u, 0x94u, 0x00u, 0x09u, 0xc0u, 0x27u,
            0x00u, 0x05u, 0x00u, 0x00u, 0x80u, 0x00u, 0x40u, 0xc2u, 0xa4u, 0x00u, 0x2fu, 0x80u, 0x01u, 0x00u, 0x00u, 0x00u,
            0x78u, 0x00u, 0x08u, 0xc2u, 0xa4u, 0x00u, 0x04u, 0x40u, 0x00u, 0x00u, 0x08u
        )

        val packet = DnsPacket.parse(data.asByteArray())
        assertEquals(QueryResponse.Response.value.toInt(), packet.header.queryResponse)
        assertEquals(DnsOpcode.StandardQuery.value.toInt(), packet.header.opcode)
        assertTrue(packet.header.authoritativeAnswer)
        assertEquals(false, packet.header.truncated)
        assertEquals(false, packet.header.recursionDesired)
        assertEquals(false, packet.header.recursionAvailable)
        assertEquals(false, packet.header.answerAuthenticated)
        assertEquals(false, packet.header.nonAuthenticatedData)
        assertEquals(DnsResponseCode.NoError, packet.header.responseCode)
        assertEquals(0, packet.questions.size)
        assertEquals(1, packet.answers.size)
        assertEquals(0, packet.authorities.size)
        assertEquals(6, packet.additionals.size)

        val firstAnswer = packet.answers[0]
        assertEquals("_ipp._tcp.local", firstAnswer.name)
        assertEquals(ResourceRecordType.PTR.value.toInt(), firstAnswer.type)
        assertEquals(ResourceRecordClass.IN.value.toInt(), firstAnswer.clazz)
        assertEquals(false, firstAnswer.cacheFlush)
        assertEquals(4500u, firstAnswer.timeToLive)
        assertEquals(30, firstAnswer.dataLength)
        assertEquals("Brother DCP-L3550CDW series._ipp._tcp.local", firstAnswer.getDataReader().readPTRRecord().domainName)

        val firstAdditional = packet.additionals[0]
        assertEquals("Brother DCP-L3550CDW series._ipp._tcp.local", firstAdditional.name)
        assertEquals(ResourceRecordType.TXT.value.toInt(), firstAdditional.type)
        assertEquals(ResourceRecordClass.IN.value.toInt(), firstAdditional.clazz)
        assertEquals(true, firstAdditional.cacheFlush)
        assertEquals(4500u, firstAdditional.timeToLive)
        assertEquals(595, firstAdditional.dataLength)

        val txtRecord = firstAdditional.getDataReader().readTXTRecord()
        assertContentEquals(arrayOf(
            "txtvers=1",
            "qtotal=1",
            "pdl=application/octet-stream,image/urf,image/jpeg,image/pwg-raster",
            "rp=ipp/print",
            "note=",
            "ty=Brother DCP-L3550CDW series",
            "product=(Brother DCP-L3550CDW series)",
            "adminurl=http://BRW105BAD4A1570.local./net/net/airprint.html",
            "priority=25",
            "usb_MFG=Brother",
            "usb_MDL=DCP-L3550CDW series",
            "usb_CMD=PJL,PCL,PCLXL,URF",
            "Color=T",
            "Copies=T",
            "Duplex=T",
            "Fax=F",
            "Scan=T",
            "PaperCustom=T",
            "Binary=T",
            "Transparent=T",
            "TBCP=F",
            "URF=SRGB24,W8,CP1,IS4-1,MT1-3-4-5-8-11,OB10,PQ4,RS600,V1.4,DM1",
            "kind=document,envelope,label,postcard",
            "PaperMax=legal-A4",
            "UUID=e3248000-80ce-11db-8000-3c2af4aac0a4",
            "print_wfds=T",
            "mopria-certified=1.3"
        ), txtRecord.texts.toTypedArray())

        val aRecord = packet.additionals[1].getDataReader().readARecord()
        assertEquals(InetAddress.getByName("192.168.1.197"), aRecord.address)

        val aaaaRecord = packet.additionals[2].getDataReader().readAAAARecord()
        assertEquals(InetAddress.getByName("fe80::125b:adff:fe4a:1570"), aaaaRecord.address)

        val srvRecord = packet.additionals[3].getDataReader().readSRVRecord()
        assertEquals("BRW105BAD4A1570.local", srvRecord.target)
        assertEquals(0, srvRecord.weight.toInt())
        assertEquals(0, srvRecord.priority.toInt())
        assertEquals(631, srvRecord.port.toInt())

        val nSECRecord = packet.additionals[4].getDataReader().readNSECRecord()
        assertEquals("Brother DCP-L3550CDW series._ipp._tcp.local", nSECRecord.ownerName)
        assertEquals(1, nSECRecord.typeBitMaps.size)
        assertEquals(0, nSECRecord.typeBitMaps[0].first)
        assertContentEquals(byteArrayOf(0, 0, 128.toByte(), 0, 64), nSECRecord.typeBitMaps[0].second)
    }

    @Test
    fun `ParseSamsungTV`() {
        val data = loadByteArray("samsung-airplay.hex")
        val packet = DnsPacket.parse(data)
        assertEquals(QueryResponse.Response.value.toInt(), packet.header.queryResponse)
        assertEquals(DnsOpcode.StandardQuery.value.toInt(), packet.header.opcode)
        assertTrue(packet.header.authoritativeAnswer)
        assertEquals(false, packet.header.truncated)
        assertEquals(false, packet.header.recursionDesired)
        assertEquals(false, packet.header.recursionAvailable)
        assertEquals(false, packet.header.answerAuthenticated)
        assertEquals(false, packet.header.nonAuthenticatedData)
        assertEquals(DnsResponseCode.NoError, packet.header.responseCode)
        assertEquals(0, packet.questions.size)
        assertEquals(6, packet.answers.size)
        assertEquals(0, packet.authorities.size)
        assertEquals(4, packet.additionals.size)

        assertEquals("9.1.168.192.in-addr.arpa", packet.answers[0].name)
        assertEquals(ResourceRecordType.PTR.value.toInt(), packet.answers[0].type)
        assertEquals(ResourceRecordClass.IN.value.toInt(), packet.answers[0].clazz)
        assertTrue(packet.answers[0].cacheFlush)
        assertEquals(120u, packet.answers[0].timeToLive)
        assertEquals(15, packet.answers[0].dataLength)
        assertEquals("Samsung.local", packet.answers[0].getDataReader().readPTRRecord().domainName)

        val txtRecord = packet.answers[1].getDataReader().readTXTRecord()
        assertContentEquals(arrayOf(
            "acl=0",
            "deviceid=D4:9D:C0:2F:52:16",
            "features=0x7F8AD0,0x38BCB46",
            "rsf=0x3",
            "fv=p20.0.1",
            "flags=0x244",
            "model=URU8000",
            "manufacturer=Samsung",
            "serialNumber=0EQC3HDM900064X",
            "protovers=1.1",
            "srcvers=377.17.24.6",
            "pi=ED:0C:A5:ED:10:08",
            "psi=00000000-0000-0000-0000-ED0CA5ED1008",
            "gid=00000000-0000-0000-0000-ED0CA5ED1008",
            "gcgl=0",
            "pk=d25488cbff1334756165cd7229a235475ef591f2595f38ed251d46b8a4d2345d"
        ), txtRecord.texts.toTypedArray())

        val srvRecord = packet.answers[4].getDataReader().readSRVRecord()
        assertEquals(33482, srvRecord.port.toInt())
        assertEquals(0, srvRecord.priority.toInt())
        assertEquals(0, srvRecord.weight.toInt())
        assertEquals("Samsung.local", srvRecord.target)

        val aRecord = packet.answers[5].getDataReader().readARecord()
        assertEquals(InetAddress.getByName("192.168.1.9"), aRecord.address)

        val nSECRecord = packet.additionals[0].getDataReader().readNSECRecord()
        assertEquals("9.1.168.192.in-addr.arpa", nSECRecord.ownerName)
        assertEquals(1, nSECRecord.typeBitMaps.size)
        assertEquals(0, nSECRecord.typeBitMaps[0].first)
        assertContentEquals(byteArrayOf(0, 8), nSECRecord.typeBitMaps[0].second)

        val optRecord = packet.additionals[3].getDataReader().readOPTRecord()
        assertEquals(1, optRecord.options.size)
        assertEquals(65001, optRecord.options[0].code.toInt())
        assertEquals(5, optRecord.options[0].data.size)
        assertContentEquals(byteArrayOf(0, 0, 116, 206.toByte(), 97), optRecord.options[0].data)
    }

    @Test
    fun `UnicodeTest`() {
        val data = ubyteArrayOf(
            0x00u, 0x00u, 0x84u, 0x00u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x01u, 0x15u, 0x41u, 0x69u, 0x64u,
            0x61u, 0x6Eu, 0xE2u, 0x80u, 0x99u, 0x73u, 0x20u, 0x4Du, 0x61u, 0x63u, 0x42u, 0x6Fu, 0x6Fu, 0x6Bu, 0x20u, 0x50u,
            0x72u, 0x6Fu, 0x0Fu, 0x5Fu, 0x63u, 0x6Fu, 0x6Du, 0x70u, 0x61u, 0x6Eu, 0x69u, 0x6Fu, 0x6Eu, 0x2Du, 0x6Cu, 0x69u,
            0x6Eu, 0x6Bu, 0x04u, 0x5Fu, 0x74u, 0x63u, 0x70u, 0x05u, 0x6Cu, 0x6Fu, 0x63u, 0x61u, 0x6Cu, 0x00u, 0x00u, 0x10u,
            0x80u, 0x01u, 0x00u, 0x00u, 0x11u, 0x94u, 0x00u, 0x5Bu, 0x16u, 0x72u, 0x70u, 0x42u, 0x41u, 0x3Du, 0x30u, 0x33u,
            0x3Au, 0x43u, 0x32u, 0x3Au, 0x33u, 0x33u, 0x3Au, 0x38u, 0x36u, 0x3Au, 0x33u, 0x43u, 0x3Au, 0x45u, 0x45u, 0x11u,
            0x72u, 0x70u, 0x41u, 0x44u, 0x3Du, 0x66u, 0x33u, 0x33u, 0x37u, 0x61u, 0x38u, 0x61u, 0x32u, 0x38u, 0x64u, 0x35u,
            0x31u, 0x0Cu, 0x72u, 0x70u, 0x46u, 0x6Cu, 0x3Du, 0x30u, 0x78u, 0x32u, 0x30u, 0x30u, 0x30u, 0x30u, 0x11u, 0x72u,
            0x70u, 0x48u, 0x4Eu, 0x3Du, 0x31u, 0x66u, 0x66u, 0x64u, 0x64u, 0x64u, 0x66u, 0x33u, 0x63u, 0x39u, 0x65u, 0x33u,
            0x07u, 0x72u, 0x70u, 0x4Du, 0x61u, 0x63u, 0x3Du, 0x30u, 0x0Au, 0x72u, 0x70u, 0x56u, 0x72u, 0x3Du, 0x33u, 0x36u,
            0x30u, 0x2Eu, 0x34u, 0xC0u, 0x0Cu, 0x00u, 0x2Fu, 0x80u, 0x01u, 0x00u, 0x00u, 0x11u, 0x94u, 0x00u, 0x09u, 0xC0u,
            0x0Cu, 0x00u, 0x05u, 0x00u, 0x00u, 0x80u, 0x00u, 0x40u
        )

        val packet = DnsPacket.parse(data.asByteArray())
        assertEquals("Aidan’s MacBook Pro._companion-link._tcp.local", packet.additionals[0].name)
    }

    /*@Test
    fun `TestReadDomainName`() {
        val data = ubyteArrayOf(
            0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x5Fu, 0x67u, 0x6Fu,
            0x6Fu, 0x67u, 0x6Cu, 0x65u, 0x63u, 0x61u, 0x73u, 0x74u, 0x04u, 0x5Fu, 0x74u, 0x63u, 0x70u, 0x05u, 0x6Cu, 0x6Fu,
            0x63u, 0x61u, 0x6Cu, 0xC0u, 0x0Cu, 0x00u, 0x0Cu, 0x00u, 0x01u, 0x08u, 0x5Fu, 0x61u, 0x69u, 0x72u, 0x70u, 0x6Cu,
            0x61u, 0x79u, 0xC0u, 0x18u, 0x00u, 0x0Cu, 0x00u, 0x01u, 0x09u, 0x5Fu, 0x66u, 0x61u, 0x73u, 0x74u, 0x63u, 0x61u,
            0x73u, 0x74u, 0xC0u, 0x18u, 0x00u, 0x0Cu, 0x00u, 0x01u, 0x06u, 0x5Fu, 0x66u, 0x63u, 0x61u, 0x73u, 0x74u, 0xC0u,
            0x18u, 0x00u, 0x0Cu, 0x00u, 0x01u
        )

        val packet = DnsPacket.parse(data.asByteArray())
        println()
    }*/

    private fun loadByteArray(name: String): ByteArray {
        javaClass.classLoader.getResourceAsStream(name).use { input ->
            requireNotNull(input) { "File not found: $name" }
            val result = ByteArrayOutputStream()
            val buffer = ByteArray(4096)
            var length: Int

            while ((input.read(buffer).also { length = it }) > 0) {
                result.write(buffer, 0, length)
            }
            return result.toByteArray()
        }
    }

    @Test
    fun `ReserializeDnsPrinter`() {
        val data = loadByteArray("samsung-airplay.hex")
        val packet = DnsPacket.parse(data)
        val writer = DnsWriter()
        writer.writePacket(
            header = packet.header,
            questionCount = packet.questions.size,
            questionWriter = { _, _ -> },
            answerCount = packet.answers.size,
            answerWriter = { w, i ->
                w.write(packet.answers[i]) { v ->
                    val reader = packet.answers[i].getDataReader()
                    when (i) {
                        0, 2, 3 -> v.write(reader.readPTRRecord())
                        1 -> v.write(reader.readTXTRecord())
                        4 -> v.write(reader.readSRVRecord())
                        5 -> v.write(reader.readARecord())
                    }
                }
            },
            authorityCount = packet.authorities.size,
            authorityWriter = { _, _ -> },
            additionalsCount = packet.additionals.size,
            additionalWriter = { w, i ->
                w.write(packet.additionals[i]) { v ->
                    val reader = packet.additionals[i].getDataReader()
                    when (i) {
                        0, 1, 2 -> v.write(reader.readNSECRecord())
                        3 -> v.write(reader.readOPTRecord())
                    }
                }
            }
        )

        assertContentEquals(data, writer.toByteArray())
    }
    */
}