package dns

import (
	
	
	
	
	
	
	
)

// DoTLookuper resolves TXT records using DNS-over-TLS.
//
// Address is a host:port pair. TLSConfig may be nil to use the default TLS
// configuration.
type DoTLookuper struct {
	Address   string
	TLSConfig *tls.Config
	Dialer    *net.Dialer
}

// LookupTXT resolves name as TXT using DNS-over-TLS.
func ( *DoTLookuper) ( context.Context,  string) ([]string, error) {
	if  == nil || .Address == "" {
		return nil, fmt.Errorf("dot: missing server address")
	}
	,  := packTXTQuery()
	if  != nil {
		return nil, 
	}
	 := .Dialer
	if  == nil {
		 = &net.Dialer{Timeout: DNSTimeout}
	}
	 := .TLSConfig
	if  == nil {
		 = &tls.Config{MinVersion: tls.VersionTLS12}
	}
	,  := tls.DialWithDialer(, "tcp", .Address, )
	if  != nil {
		return nil, fmt.Errorf("dot lookup %q: dial: %w", , )
	}
	defer .Close()
	if ,  := .Deadline();  {
		.SetDeadline()
	} else {
		.SetDeadline(time.Now().Add(DNSTimeout))
	}
	if  := writeDNSMessage(, );  != nil {
		return nil, fmt.Errorf("dot lookup %q: write query: %w", , )
	}
	,  := readDNSMessage()
	if  != nil {
		return nil, fmt.Errorf("dot lookup %q: read response: %w", , )
	}
	,  := unpackTXTResponse()
	if  != nil {
		return nil, fmt.Errorf("dot lookup %q: %w", , )
	}
	return , nil
}

func writeDNSMessage( io.Writer,  []byte) error {
	if len() > 0xffff {
		return fmt.Errorf("dns message too large: %d bytes", len())
	}
	var  [2]byte
	binary.BigEndian.PutUint16([:], uint16(len()))
	if ,  := .Write([:]);  != nil {
		return 
	}
	,  := .Write()
	return 
}

func readDNSMessage( io.Reader) ([]byte, error) {
	var  [2]byte
	if ,  := io.ReadFull(, [:]);  != nil {
		return nil, 
	}
	 := binary.BigEndian.Uint16([:])
	 := make([]byte, )
	if ,  := io.ReadFull(, );  != nil {
		return nil, 
	}
	return , nil
}