package dns

import (
	"context"
	"net/netip"
	"os"
	"time"

	"darvaza.org/core"
	"github.com/libdns/libdns"
)

// Add adds a machine to the DNS records
func (mgr *Manager) Add(ctx context.Context, name string, addrs ...netip.Addr) error {
	// TODO: validate name

	cur, err := mgr.GetRecords(ctx, name)
	if err != nil {
		return core.Wrap(err, "GetRecords")
	}

	// merge []SyncAddr for name
	s := mgr.asSyncRecordsMap(cur)[name+mgr.suffix]
	for _, addr := range addrs {
		s = AppendSyncAddr(s, addr)
	}

	return mgr.addSyncAddr(ctx, name, s)
}

func (mgr *Manager) addSyncAddr(ctx context.Context, name string, s []SyncAddr) error {
	var recs []libdns.Record

	for _, a := range s {
		recs = append(recs, libdns.Record{
			ID:    a.ID,
			Name:  name + mgr.suffix,
			Type:  core.IIf(a.Addr.Is6(), "AAAA", "A"),
			TTL:   time.Second,
			Value: a.Addr.String(),
		})
	}

	SortRecords(recs)
	err := writeRecords(recs, os.Stdout)
	if err != nil {
		return err
	}

	_, err = mgr.p.SetRecords(ctx, mgr.domain, recs)
	return err
}

// AppendSyncAddr appends a [netip.Addr] to a [SyncAddr] slice
// if the address is new.
func AppendSyncAddr(s []SyncAddr, addr netip.Addr) []SyncAddr {
	for _, se := range s {
		if se.Addr.Compare(addr) == 0 {
			// found
			return s
		}
	}

	s = append(s, SyncAddr{
		Addr: addr,
		TTL:  time.Second,
	})
	return s
}