package dns

import (
	
	
	
	
	
	

	
)

// DoHLookuper resolves TXT records using DNS-over-HTTPS.
//
// It sends RFC 8484 POST requests with Content-Type application/dns-message.
// The zero value is not usable; set URL before calling LookupTXT.
type DoHLookuper struct {
	// URL is the DNS-over-HTTPS endpoint.
	URL string
	// HTTPClient sends requests. If nil, [http.DefaultClient] is used.
	HTTPClient *http.Client
}

// LookupTXT resolves name as TXT using DNS-over-HTTPS.
func ( *DoHLookuper) ( context.Context,  string) ([]string, error) {
	if  == nil || .URL == "" {
		return nil, fmt.Errorf("doh: missing endpoint url")
	}
	,  := packTXTQuery()
	if  != nil {
		return nil, 
	}
	,  := http.NewRequestWithContext(, http.MethodPost, .URL, bytes.NewReader())
	if  != nil {
		return nil, 
	}
	.Header.Set("Accept", "application/dns-message")
	.Header.Set("Content-Type", "application/dns-message")

	 := .HTTPClient
	if  == nil {
		 = http.DefaultClient
	}
	,  := .Do()
	if  != nil {
		return nil, fmt.Errorf("doh lookup %q: %w", , )
	}
	defer .Body.Close()
	if .StatusCode < 200 || .StatusCode >= 300 {
		return nil, fmt.Errorf("doh lookup %q: http status %s", , .Status)
	}
	,  := io.ReadAll(io.LimitReader(.Body, 64*1024))
	if  != nil {
		return nil, fmt.Errorf("doh lookup %q: read response: %w", , )
	}
	,  := unpackTXTResponse()
	if  != nil {
		return nil, fmt.Errorf("doh lookup %q: %w", , )
	}
	return , nil
}

func packTXTQuery( string) ([]byte, error) {
	,  := dnsmessage.NewName(ensureTrailingDot())
	if  != nil {
		return nil, fmt.Errorf("doh: bad name %q: %w", , )
	}
	 := dnsmessage.NewBuilder(nil, dnsmessage.Header{RecursionDesired: true})
	if  := .StartQuestions();  != nil {
		return nil, 
	}
	if  := .Question(dnsmessage.Question{
		Name:  ,
		Type:  dnsmessage.TypeTXT,
		Class: dnsmessage.ClassINET,
	});  != nil {
		return nil, 
	}
	,  := .Finish()
	if  != nil {
		return nil, 
	}
	return , nil
}

func unpackTXTResponse( []byte) ([]string, error) {
	var  dnsmessage.Parser
	if ,  := .Start();  != nil {
		return nil, 
	}
	if  := .SkipAllQuestions();  != nil {
		return nil, 
	}
	var  []string
	for {
		,  := .AnswerHeader()
		if  == dnsmessage.ErrSectionDone {
			break
		}
		if  != nil {
			return nil, 
		}
		if .Type != dnsmessage.TypeTXT {
			if  := .SkipAnswer();  != nil {
				return nil, 
			}
			continue
		}
		,  := .TXTResource()
		if  != nil {
			return nil, 
		}
		 = append(, strings.Join(.TXT, ""))
	}
	if len() == 0 {
		return nil, fmt.Errorf("no TXT answers")
	}
	return , nil
}