package peer

import (
	"log"
	"net"
	"time"

	"golang.org/x/crypto/nacl/sign"
)

func createLocalDiscoveryPacket(localIP byte, signingKey []byte) []byte {
	h := Header{
		SourceIP: localIP,
		DestIP:   255,
	}
	buf := make([]byte, headerSize)
	h.Marshal(buf)
	out := make([]byte, headerSize+signingOverhead)
	return sign.Sign(out[:0], buf, (*[64]byte)(signingKey))
}

func headerFromLocalDiscoveryPacket(pkt []byte) (h Header, ok bool) {
	if len(pkt) != headerSize+signingOverhead {
		return
	}

	h.Parse(pkt[signingOverhead:])
	ok = true
	return
}

func verifyLocalDiscoveryPacket(pkt, buf []byte, pubSignKey []byte) bool {
	_, ok := sign.Open(buf[:0], pkt, (*[32]byte)(pubSignKey))
	return ok
}

// ----------------------------------------------------------------------------

func RunMCWriter(localIP byte, signingKey []byte) {
	discoveryPacket := createLocalDiscoveryPacket(localIP, signingKey)

	conn, err := net.ListenMulticastUDP("udp", nil, multicastAddr)
	if err != nil {
		log.Fatalf("[MCWriter] Failed to bind to multicast address: %v", err)
	}

	for range time.Tick(broadcastInterval) {
		log.Printf("[MCWriter] Broadcasting on %v...", multicastAddr)
		_, err := conn.WriteToUDP(discoveryPacket, multicastAddr)
		if err != nil {
			log.Printf("[MCWriter] Failed to write multicast: %v", err)
		}
	}
}
