//go:build ignore

// dnsutil_generate generates zdnsutil.go which is a copy of dnsutil/shared.go and internalized.

package main

import (
	"bytes"
	"flag"
	"go/ast"
	"go/printer"
	"go/token"
	"log"
	"strings"

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

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

`

func main() {
	flag.Parse()
	node, fset, err := generate.Ast("dnsutil/shared.go")
	if err != nil {
		log.Fatalf("Failed to generate %v: %v", outs, err)
	}

	node.Name = ast.NewIdent("dns")
	// put 'dnsutil' before each name.
	for _, decl := range node.Decls {
		if fn, ok := decl.(*ast.FuncDecl); ok && fn.Name.IsExported() {
			fn.Name.Name = "dnsutil" + fn.Name.Name
		}
	}
	// remove import
	newImports := []ast.Spec{}
	for _, imp := range node.Imports {
		if strings.Trim(imp.Path.Value, `"`) != "codeberg.org/miekg/dns" {
			newImports = append(newImports, imp)
		}
	}

	for _, decl := range node.Decls {
		if genDecl, ok := decl.(*ast.GenDecl); ok && genDecl.Tok == token.IMPORT {
			genDecl.Specs = newImports
			break
		}
	}

	source := &bytes.Buffer{}
	source.WriteString(hdr)
	if err := printer.Fprint(source, fset, node); err != nil {
		log.Fatalf("Failed to generate %v: %v", outs, err)
	}

	// silly: go over bytes and remove `dns.` everyhwere.
	source2 := bytes.ReplaceAll(source.Bytes(), []byte(`dns.`), nil)
	// but then "fix" it for function calls: Fqdn and Next who are now named dnsutilIsFqdn, dnsutilFqdn, etc.
	for _, fix := range [][]byte{[]byte(" IsFqdn(s)"), []byte(" Fqdn(s)"), []byte(" Next(s, off)"), []byte(" IsName(s)")} {
		replace := append([]byte(" dnsutil"), fix[1:]...)
		source2 = bytes.ReplaceAll(source2, fix, replace)
	}
	for _, out := range outs {
		switch out {
		case "deleg/zdnsutil.go":
			source2 = bytes.Replace(source2, []byte("package dns"), []byte("package deleg"), 1)
		case "svcb/zdnsutil.go":
			source2 = bytes.Replace(source2, []byte("package deleg"), []byte("package svcb"), 1)
		case "rdata/zdnsutil.go":
			source2 = bytes.Replace(source2, []byte("package svcb"), []byte("package rdata"), 1)
		}
		generate.Write(bytes.NewBuffer(source2), out)
	}
}

var outs = []string{"zdnsutil.go", "deleg/zdnsutil.go", "svcb/zdnsutil.go", "rdata/zdnsutil.go"}
