// Copyright 2016 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

// Generate builtin.go from builtin/runtime.go.

package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

var stdout = flag.Bool("stdout", false, "write to stdout instead of builtin.go")

func main() {
	flag.Parse()

	var b bytes.Buffer
	fmt.Fprintln(&b, "// Code generated by mkbuiltin.go. DO NOT EDIT.")
	fmt.Fprintln(&b)
	fmt.Fprintln(&b, "package typecheck")
	fmt.Fprintln(&b)
	fmt.Fprintln(&b, `import (`)
	fmt.Fprintln(&b, `      "cmd/compile/internal/types"`)
	fmt.Fprintln(&b, `      "cmd/internal/src"`)
	fmt.Fprintln(&b, `)`)

	mkbuiltin(&b, "runtime")

	out, err := format.Source(b.Bytes())
	if err != nil {
		log.Fatal(err)
	}
	if *stdout {
		_, err = os.Stdout.Write(out)
	} else {
		err = ioutil.WriteFile("builtin.go", out, 0666)
	}
	if err != nil {
		log.Fatal(err)
	}
}

func mkbuiltin(w io.Writer, name string) {
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, filepath.Join("builtin", name+".go"), nil, 0)
	if err != nil {
		log.Fatal(err)
	}

	var interner typeInterner

	fmt.Fprintf(w, "var %sDecls = [...]struct { name string; tag int; typ int }{\n", name)
	for _, decl := range f.Decls {
		switch decl := decl.(type) {
		case *ast.FuncDecl:
			if decl.Recv != nil {
				log.Fatal("methods unsupported")
			}
			if decl.Body != nil {
				log.Fatal("unexpected function body")
			}
			fmt.Fprintf(w, "{%q, funcTag, %d},\n", decl.Name.Name, interner.intern(decl.Type))
		case *ast.GenDecl:
			if decl.Tok == token.IMPORT {
				if len(decl.Specs) != 1 || decl.Specs[0].(*ast.ImportSpec).Path.Value != "\"unsafe\"" {
					log.Fatal("runtime cannot import other package")
				}
				continue
			}
			if decl.Tok != token.VAR {
				log.Fatal("unhandled declaration kind", decl.Tok)
			}
			for _, spec := range decl.Specs {
				spec := spec.(*ast.ValueSpec)
				if len(spec.Values) != 0 {
					log.Fatal("unexpected values")
				}
				typ := interner.intern(spec.Type)
				for _, name := range spec.Names {
					fmt.Fprintf(w, "{%q, varTag, %d},\n", name.Name, typ)
				}
			}
		default:
			log.Fatal("unhandled decl type", decl)
		}
	}
	fmt.Fprintln(w, "}")

	fmt.Fprintln(w, `
// Not inlining this function removes a significant chunk of init code.
//go:noinline
func newSig(params, results []*types.Field) *types.Type {
	return types.NewSignature(types.NoPkg, nil, nil, params, results)
}

func params(tlist ...*types.Type) []*types.Field {
	flist := make([]*types.Field, len(tlist))
	for i, typ := range tlist {
		flist[i] = types.NewField(src.NoXPos, nil, typ)
	}
	return flist
}`)

	fmt.Fprintln(w)
	fmt.Fprintf(w, "func %sTypes() []*types.Type {\n", name)
	fmt.Fprintf(w, "var typs [%d]*types.Type\n", len(interner.typs))
	for i, typ := range interner.typs {
		fmt.Fprintf(w, "typs[%d] = %s\n", i, typ)
	}
	fmt.Fprintln(w, "return typs[:]")
	fmt.Fprintln(w, "}")
}

// typeInterner maps Go type expressions to compiler code that
// constructs the denoted type. It recognizes and reuses common
// subtype expressions.
type typeInterner struct {
	typs []string
	hash map[string]int
}

func (i *typeInterner) intern(t ast.Expr) int {
	x := i.mktype(t)
	v, ok := i.hash[x]
	if !ok {
		v = len(i.typs)
		if i.hash == nil {
			i.hash = make(map[string]int)
		}
		i.hash[x] = v
		i.typs = append(i.typs, x)
	}
	return v
}

func (i *typeInterner) subtype(t ast.Expr) string {
	return fmt.Sprintf("typs[%d]", i.intern(t))
}

func (i *typeInterner) mktype(t ast.Expr) string {
	switch t := t.(type) {
	case *ast.Ident:
		switch t.Name {
		case "byte":
			return "types.ByteType"
		case "rune":
			return "types.RuneType"
		}
		return fmt.Sprintf("types.Types[types.T%s]", strings.ToUpper(t.Name))
	case *ast.SelectorExpr:
		if t.X.(*ast.Ident).Name != "unsafe" || t.Sel.Name != "Pointer" {
			log.Fatalf("unhandled type: %#v", t)
		}
		return "types.Types[types.TUNSAFEPTR]"

	case *ast.ArrayType:
		if t.Len == nil {
			return fmt.Sprintf("types.NewSlice(%s)", i.subtype(t.Elt))
		}
		return fmt.Sprintf("types.NewArray(%s, %d)", i.subtype(t.Elt), intconst(t.Len))
	case *ast.ChanType:
		dir := "types.Cboth"
		switch t.Dir {
		case ast.SEND:
			dir = "types.Csend"
		case ast.RECV:
			dir = "types.Crecv"
		}
		return fmt.Sprintf("types.NewChan(%s, %s)", i.subtype(t.Value), dir)
	case *ast.FuncType:
		return fmt.Sprintf("newSig(%s, %s)", i.fields(t.Params, false), i.fields(t.Results, false))
	case *ast.InterfaceType:
		if len(t.Methods.List) != 0 {
			log.Fatal("non-empty interfaces unsupported")
		}
		return "types.Types[types.TINTER]"
	case *ast.MapType:
		return fmt.Sprintf("types.NewMap(%s, %s)", i.subtype(t.Key), i.subtype(t.Value))
	case *ast.StarExpr:
		return fmt.Sprintf("types.NewPtr(%s)", i.subtype(t.X))
	case *ast.StructType:
		return fmt.Sprintf("types.NewStruct(types.NoPkg, %s)", i.fields(t.Fields, true))

	default:
		log.Fatalf("unhandled type: %#v", t)
		panic("unreachable")
	}
}

func (i *typeInterner) fields(fl *ast.FieldList, keepNames bool) string {
	if fl == nil || len(fl.List) == 0 {
		return "nil"
	}

	var res []string
	for _, f := range fl.List {
		typ := i.subtype(f.Type)
		if len(f.Names) == 0 {
			res = append(res, typ)
		} else {
			for _, name := range f.Names {
				if keepNames {
					res = append(res, fmt.Sprintf("types.NewField(src.NoXPos, Lookup(%q), %s)", name.Name, typ))
				} else {
					res = append(res, typ)
				}
			}
		}
	}

	if keepNames {
		return fmt.Sprintf("[]*types.Field{%s}", strings.Join(res, ", "))
	}
	return fmt.Sprintf("params(%s)", strings.Join(res, ", "))
}

func intconst(e ast.Expr) int64 {
	switch e := e.(type) {
	case *ast.BasicLit:
		if e.Kind != token.INT {
			log.Fatalf("expected INT, got %v", e.Kind)
		}
		x, err := strconv.ParseInt(e.Value, 0, 64)
		if err != nil {
			log.Fatal(err)
		}
		return x
	default:
		log.Fatalf("unhandled expr: %#v", e)
		panic("unreachable")
	}
}
