package peer

import (
	"net/netip"
	"reflect"
	"testing"
)

func TestBinWriteRead_invalidAddrPort(t *testing.T) {
	addr := netip.AddrPort{}
	buf := make([]byte, 1024)
	buf = newBinWriter(buf).
		AddrPort(addr).
		Build()

	var addr2 netip.AddrPort
	err := newBinReader(buf).
		AddrPort(&addr2).
		Error()
	if err != nil {
		t.Fatal(err)
	}

	if addr2.IsValid() {
		t.Fatal(addr, addr2)
	}
}

func TestBinWriteRead(t *testing.T) {
	buf := make([]byte, 1024)

	type Item struct {
		Type     byte
		TraceID  uint64
		Addrs    [8]netip.AddrPort
		DestAddr netip.AddrPort
	}

	in := Item{
		1,
		2,
		[8]netip.AddrPort{},
		netip.AddrPortFrom(netip.AddrFrom4([4]byte{1, 2, 3, 4}), 22),
	}

	in.Addrs[0] = netip.AddrPortFrom(netip.AddrFrom4([4]byte{0, 1, 2, 3}), 20)
	in.Addrs[2] = netip.AddrPortFrom(netip.AddrFrom4([4]byte{2, 3, 4, 5}), 22)
	in.Addrs[3] = netip.AddrPortFrom(netip.AddrFrom4([4]byte{2, 3, 4, 3}), 23)
	in.Addrs[4] = netip.AddrPortFrom(netip.AddrFrom4([4]byte{2, 3, 4, 4}), 24)
	in.Addrs[5] = netip.AddrPortFrom(netip.AddrFrom4([4]byte{2, 3, 4, 5}), 25)
	in.Addrs[6] = netip.AddrPortFrom(netip.AddrFrom4([4]byte{2, 3, 4, 6}), 26)
	in.Addrs[7] = netip.AddrPortFrom(netip.AddrFrom4([4]byte{7, 8, 9, 7}), 27)

	buf = newBinWriter(buf).
		Byte(in.Type).
		Uint64(in.TraceID).
		AddrPort(in.DestAddr).
		AddrPort8(in.Addrs).
		Build()

	out := Item{}

	err := newBinReader(buf).
		Byte(&out.Type).
		Uint64(&out.TraceID).
		AddrPort(&out.DestAddr).
		AddrPort8(&out.Addrs).
		Error()
	if err != nil {
		t.Fatal(err)
	}

	if !reflect.DeepEqual(in, out) {
		t.Fatal(in, out)
	}
}
