package dns

import (
	"bytes"
	"fmt"
	"io"
	"net/netip"
)

// WriteTo writes the DNS data for the cluster
func (mgr *Manager) WriteTo(w io.Writer) (int64, error) {
	var buf bytes.Buffer

	cache := make(map[string][]netip.Addr)

	// zones
	for _, zoneName := range mgr.genZonesSorted() {
		z := mgr.zones[zoneName]

		mgr.writeZoneHosts(&buf, z)

		// zone alias
		addrs := mgr.genZoneAddresses(z)

		rr := AddrRecord{
			Name: mgr.fqdn(zoneName + mgr.suffix),
			Addr: addrs,
		}
		_, _ = rr.WriteTo(&buf)

		// and cache for regions
		cache[zoneName] = addrs
	}

	// regions, sorted
	for _, name := range mgr.genRegionsSorted() {
		addrs := mgr.genRegionAddressesCached(name, cache)

		mgr.writeRegionAddresses(&buf, name, addrs)
	}

	return buf.WriteTo(w)
}

func (mgr *Manager) writeZoneHosts(w io.Writer, z *Zone) {
	_, _ = fmt.Fprintf(w, ";\n; %s\n;\n", z.Name)

	for _, rr := range mgr.genZoneHostRecords(z) {
		rr.Name = mgr.fqdn(rr.Name)
		_, _ = rr.WriteTo(w)
	}
}

func (mgr *Manager) writeRegionAddresses(w io.Writer, name string, addrs []netip.Addr) {
	_, _ = fmt.Fprintf(w, "; %s\n", name)

	rr := AddrRecord{
		Name: mgr.fqdn(name + mgr.suffix),
		Addr: addrs,
	}

	_, _ = rr.WriteTo(w)
}