// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build ignore
// +build ignore

package main

import (
	"bytes"
	"fmt"
	"go/format"
	"go/types"
	"io/ioutil"
	"log"
	"reflect"
	"sort"
	"strings"

	"golang.org/x/tools/go/packages"
)

var irPkg *types.Package
var buf bytes.Buffer

func main() {
	cfg := &packages.Config{
		Mode: packages.NeedSyntax | packages.NeedTypes,
	}
	pkgs, err := packages.Load(cfg, "cmd/compile/internal/ir")
	if err != nil {
		log.Fatal(err)
	}
	irPkg = pkgs[0].Types

	fmt.Fprintln(&buf, "// Code generated by mknode.go. DO NOT EDIT.")
	fmt.Fprintln(&buf)
	fmt.Fprintln(&buf, "package ir")
	fmt.Fprintln(&buf)
	fmt.Fprintln(&buf, `import "fmt"`)

	scope := irPkg.Scope()
	for _, name := range scope.Names() {
		if strings.HasPrefix(name, "mini") {
			continue
		}

		obj, ok := scope.Lookup(name).(*types.TypeName)
		if !ok {
			continue
		}
		typ := obj.Type().(*types.Named)
		if !implementsNode(types.NewPointer(typ)) {
			continue
		}

		fmt.Fprintf(&buf, "\n")
		fmt.Fprintf(&buf, "func (n *%s) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }\n", name)

		switch name {
		case "Name", "Func":
			// Too specialized to automate.
			continue
		}

		forNodeFields(typ,
			"func (n *%[1]s) copy() Node { c := *n\n",
			"",
			"c.%[1]s = copy%[2]s(c.%[1]s)",
			"return &c }\n")

		forNodeFields(typ,
			"func (n *%[1]s) doChildren(do func(Node) bool) bool {\n",
			"if n.%[1]s != nil && do(n.%[1]s) { return true }",
			"if do%[2]s(n.%[1]s, do) { return true }",
			"return false }\n")

		forNodeFields(typ,
			"func (n *%[1]s) editChildren(edit func(Node) Node) {\n",
			"if n.%[1]s != nil { n.%[1]s = edit(n.%[1]s).(%[2]s) }",
			"edit%[2]s(n.%[1]s, edit)",
			"}\n")
	}

	makeHelpers()

	out, err := format.Source(buf.Bytes())
	if err != nil {
		// write out mangled source so we can see the bug.
		out = buf.Bytes()
	}

	err = ioutil.WriteFile("node_gen.go", out, 0666)
	if err != nil {
		log.Fatal(err)
	}
}

// needHelper maps needed slice helpers from their base name to their
// respective slice-element type.
var needHelper = map[string]string{}

func makeHelpers() {
	var names []string
	for name := range needHelper {
		names = append(names, name)
	}
	sort.Strings(names)

	for _, name := range names {
		fmt.Fprintf(&buf, sliceHelperTmpl, name, needHelper[name])
	}
}

const sliceHelperTmpl = `
func copy%[1]s(list []%[2]s) []%[2]s {
	if list == nil {
		return nil
	}
	c := make([]%[2]s, len(list))
	copy(c, list)
	return c
}
func do%[1]s(list []%[2]s, do func(Node) bool) bool {
	for _, x := range list {
		if x != nil && do(x) {
			return true
		}
	}
	return false
}
func edit%[1]s(list []%[2]s, edit func(Node) Node) {
	for i, x := range list {
		if x != nil {
			list[i] = edit(x).(%[2]s)
		}
	}
}
`

func forNodeFields(named *types.Named, prologue, singleTmpl, sliceTmpl, epilogue string) {
	fmt.Fprintf(&buf, prologue, named.Obj().Name())

	anyField(named.Underlying().(*types.Struct), func(f *types.Var) bool {
		if f.Embedded() {
			return false
		}
		name, typ := f.Name(), f.Type()

		slice, _ := typ.Underlying().(*types.Slice)
		if slice != nil {
			typ = slice.Elem()
		}

		tmpl, what := singleTmpl, types.TypeString(typ, types.RelativeTo(irPkg))
		if implementsNode(typ) {
			if slice != nil {
				helper := strings.TrimPrefix(what, "*") + "s"
				needHelper[helper] = what
				tmpl, what = sliceTmpl, helper
			}
		} else if what == "*Field" {
			// Special case for *Field.
			tmpl = sliceTmpl
			if slice != nil {
				what = "Fields"
			} else {
				what = "Field"
			}
		} else {
			return false
		}

		if tmpl == "" {
			return false
		}

		// Allow template to not use all arguments without
		// upsetting fmt.Printf.
		s := fmt.Sprintf(tmpl+"\x00 %[1]s %[2]s", name, what)
		fmt.Fprintln(&buf, s[:strings.LastIndex(s, "\x00")])
		return false
	})

	fmt.Fprintf(&buf, epilogue)
}

func implementsNode(typ types.Type) bool {
	if _, ok := typ.Underlying().(*types.Interface); ok {
		// TODO(mdempsky): Check the interface implements Node.
		// Worst case, node_gen.go will fail to compile if we're wrong.
		return true
	}

	if ptr, ok := typ.(*types.Pointer); ok {
		if str, ok := ptr.Elem().Underlying().(*types.Struct); ok {
			return anyField(str, func(f *types.Var) bool {
				return f.Embedded() && f.Name() == "miniNode"
			})
		}
	}

	return false
}

func anyField(typ *types.Struct, pred func(f *types.Var) bool) bool {
	for i, n := 0, typ.NumFields(); i < n; i++ {
		if value, ok := reflect.StructTag(typ.Tag(i)).Lookup("mknode"); ok {
			if value != "-" {
				panic(fmt.Sprintf("unexpected tag value: %q", value))
			}
			continue
		}

		f := typ.Field(i)
		if pred(f) {
			return true
		}
		if f.Embedded() {
			if typ, ok := f.Type().Underlying().(*types.Struct); ok {
				if anyField(typ, pred) {
					return true
				}
			}
		}
	}
	return false
}
