//go:build ignore

package main

import (
	"bytes"
	"flag"
	"html/template"
	"log"

	"codeberg.org/miekg/dns/internal/generate"
)

var hdr = `
// Code generated by "go run dsorr_generate.go"; DO NOT EDIT.

package dns

`

var StatefulToRR = template.Must(template.New("TypeToRR").Parse(`
// StatefulToRR is a map of constructors for each DSO RR type.
var StatefulToRR = map[uint16]func() DSO{
{{range .}}  Stateful{{.}}:  func() DSO { return new({{.}}) },
{{end}}                    }

`))

var RRToStateful = template.Must(template.New("RRToStateful").Parse(`
// RRToStateful is the reverse of StatefulToRR, implemented as a function.
func RRToStateful(rr DSO) uint16 {
    switch rr.(type) {
{{range .}}  case *{{.}}:
	return Stateful{{.}}
{{end}} }
    return StatefulNone
}

`))

var StatefulToString = template.Must(template.New("statefulToString").Parse(`
// StatefulToString is a map of strings for each DSO RR type.
var StatefulToString = map[uint16]string{
{{range .}}  Stateful{{.}}: "{{.}}",
{{end}}
}

`))

var interfaceFunc = template.Must(template.New("interfaceFunc").Parse(`
	{{range .}}  func (rr *{{.}}) Header() *Header { return &Header{Name:"."} }
func (rr *{{.}}) Stateful() bool { return true }
{{end}}

`))

const out = "zdsorr.go"

func main() {
	flag.Parse()
	types, err := generate.Types("dso_types.go")
	if err != nil {
		log.Fatalf("Failed to generate %s: %v", out, err)
	}

	source := &bytes.Buffer{}
	source.WriteString(hdr)
	if err := interfaceFunc.Execute(source, types); err != nil {
		log.Fatalf("Failed to generate %s: %v", out, err)
	}
	if err := StatefulToRR.Execute(source, types); err != nil {
		log.Fatalf("Failed to generate %s: %v", out, err)
	}
	if err := RRToStateful.Execute(source, types); err != nil {
		log.Fatalf("Failed to generate %s: %v", out, err)
	}
	if err := StatefulToString.Execute(source, types); err != nil {
		log.Fatalf("Failed to generate %s: %v", out, err)
	}

	generate.Write(source, out)
}
