package dns

import 

// PrivateRdata is an interface used for implementing "Private Use" RR types, see
// RFC 6895. This allows one to experiment with new RR types, without requesting an
// official type code. Also see dns.PrivateHandle and dns.PrivateHandleRemove.
type PrivateRdata interface {
	// String returns the text presentation of the Rdata of the Private RR.
	String() string
	// Parse parses the Rdata of the private RR.
	Parse([]string) error
	// Pack is used when packing a private RR into a buffer.
	Pack([]byte) (int, error)
	// Unpack is used when unpacking a private RR from a buffer.
	Unpack([]byte) (int, error)
	// Copy copies the Rdata into the PrivateRdata argument.
	Copy(PrivateRdata) error
	// Len returns the length in octets of the Rdata.
	Len() int
}

// PrivateRR represents an RR that uses a PrivateRdata user-defined type.
// It mocks normal RRs and implements dns.RR interface.
type PrivateRR struct {
	Hdr  RR_Header
	Data PrivateRdata

	generator func() PrivateRdata // for copy
}

// Header return the RR header of r.
func ( *PrivateRR) () *RR_Header { return &.Hdr }

func ( *PrivateRR) () string { return .Hdr.String() + .Data.String() }

// Private len and copy parts to satisfy RR interface.
func ( *PrivateRR) ( int,  map[string]struct{}) int {
	 := .Hdr.len(, )
	 += .Data.Len()
	return 
}

func ( *PrivateRR) () RR {
	// make new RR like this:
	 := &PrivateRR{.Hdr, .generator(), .generator}

	if  := .Data.Copy(.Data);  != nil {
		panic("dns: got value that could not be used to copy Private rdata: " + .Error())
	}

	return 
}

func ( *PrivateRR) ( []byte,  int,  compressionMap,  bool) (int, error) {
	,  := .Data.Pack([:])
	if  != nil {
		return len(), 
	}
	 += 
	return , nil
}

func ( *PrivateRR) ( []byte,  int) (int, error) {
	,  := .Data.Unpack([:])
	 += 
	return , 
}

func ( *PrivateRR) ( *zlexer,  string) *ParseError {
	var  lex
	 := make([]string, 0, 2) // could be 0..N elements, median is probably 1
:
	for {
		// TODO(miek): we could also be returning _QUOTE, this might or might not
		// be an issue (basically parsing TXT becomes hard)
		switch , _ = .Next(); .value {
		case zNewline, zEOF:
			break 
		case zString:
			 = append(, .token)
		}
	}

	 := .Data.Parse()
	if  != nil {
		return &ParseError{wrappedErr: , lex: }
	}

	return nil
}

func ( *PrivateRR) ( RR) bool { return false }

// PrivateHandle registers a private resource record type. It requires
// string and numeric representation of private RR type and generator function as argument.
func ( string,  uint16,  func() PrivateRdata) {
	 = strings.ToUpper()

	TypeToRR[] = func() RR { return &PrivateRR{RR_Header{}, (), } }
	TypeToString[] = 
	StringToType[] = 
}

// PrivateHandleRemove removes definitions required to support private RR type.
func ( uint16) {
	,  := TypeToString[]
	if  {
		delete(TypeToRR, )
		delete(TypeToString, )
		delete(StringToType, )
	}
}