package dns

import (
	"net"
	"strings"
	"time"

	"github.com/hashicorp/golang-lru/v2/expirable"
)

const (
	lookupCacheValidity = 30 * time.Second
	defaultPagesRepo    = "pages"
)

// TODO(#316): refactor to not use global variables
var lookupCache *expirable.LRU[string, string] = expirable.NewLRU[string, string](4096, nil, lookupCacheValidity)

// GetTargetFromDNS searches for CNAME or TXT entries on the request domain ending with MainDomainSuffix.
// If everything is fine, it returns the target data.
func GetTargetFromDNS(domain, mainDomainSuffix, firstDefaultBranch string) (targetOwner, targetRepo, targetBranch string) {
	// Get CNAME or TXT
	var cname string
	var err error

	if entry, ok := lookupCache.Get(domain); ok {
		cname = entry
	} else {
		cname, err = net.LookupCNAME(domain)
		cname = strings.TrimSuffix(cname, ".")
		if err != nil || !strings.HasSuffix(cname, mainDomainSuffix) {
			cname = ""
			// TODO: check if the A record matches!
			names, err := net.LookupTXT(domain)
			if err == nil {
				for _, name := range names {
					name = strings.TrimSuffix(strings.TrimSpace(name), ".")
					if strings.HasSuffix(name, mainDomainSuffix) {
						cname = name
						break
					}
				}
			}
		}
		_ = lookupCache.Add(domain, cname)
	}
	if cname == "" {
		return
	}
	cnameParts := strings.Split(strings.TrimSuffix(cname, mainDomainSuffix), ".")
	targetOwner = cnameParts[len(cnameParts)-1]
	if len(cnameParts) > 1 {
		targetRepo = cnameParts[len(cnameParts)-2]
	}
	if len(cnameParts) > 2 {
		targetBranch = cnameParts[len(cnameParts)-3]
	}
	if targetRepo == "" {
		targetRepo = defaultPagesRepo
	}
	if targetBranch == "" && targetRepo != defaultPagesRepo {
		targetBranch = firstDefaultBranch
	}
	// if targetBranch is still empty, the caller must find the default branch
	return
}