// Copyright 2018 The CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build ignore

package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/ast"
	"go/constant"
	"go/format"
	"go/parser"
	"go/printer"
	"go/token"
	"io"
	"io/ioutil"
	"log"
	"math/big"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strconv"
	"strings"

	"cuelang.org/go/cue"
	"cuelang.org/go/cue/errors"
	cueformat "cuelang.org/go/cue/format"
	"cuelang.org/go/cue/load"
)

const prefix = "../pkg/"

const header = `// Code generated by go generate. DO NOT EDIT.

package cue

`

const initFunc = `
func init() {
	initBuiltins(builtinPackages)
}

var _ io.Reader
`

func main() {
	flag.Parse()
	log.SetFlags(log.Lshortfile)
	log.SetOutput(os.Stdout)

	g := generator{
		w:     &bytes.Buffer{},
		decls: &bytes.Buffer{},
		fset:  token.NewFileSet(),
	}

	fmt.Fprintln(g.w, "var builtinPackages = map[string]*builtinPkg{")
	filepath.Walk(prefix, func(dir string, info os.FileInfo, err error) error {
		if err != nil {
			log.Fatal(err)
		}
		if info.Name() == "testdata" {
			return filepath.SkipDir
		}
		if info.IsDir() {
			g.processDir(dir)
		}
		return nil
	})
	fmt.Fprintln(g.w, "}")

	w := &bytes.Buffer{}
	fmt.Fprintln(w, header)

	m := map[string]*ast.ImportSpec{}
	keys := []string{}
	for _, spec := range g.imports {
		if spec.Path.Value == `"cuelang.org/go/cue"` {
			// Don't add this package.
			continue
		}
		if prev, ok := m[spec.Path.Value]; ok {
			if importName(prev) != importName(spec) {
				log.Fatalf("inconsistent name for import %s: %q != %q",
					spec.Path.Value, importName(prev), importName(spec))
			}
			continue
		}
		m[spec.Path.Value] = spec
		keys = append(keys, spec.Path.Value)
	}
	fmt.Fprintln(w, "import (")
	sort.Strings(keys)
	for _, k := range keys {
		printer.Fprint(w, g.fset, m[k])
		fmt.Fprintln(w)
	}
	fmt.Fprintln(w, ")")
	fmt.Fprintln(w, initFunc)
	io.Copy(w, g.decls)
	io.Copy(w, g.w)

	b, err := format.Source(w.Bytes())
	if err != nil {
		b = w.Bytes() // write the unformatted source
	}
	// TODO: do this in a more principled way. The best is probably to
	// put all builtins in a separate package.
	b = bytes.Replace(b, []byte("cue."), []byte(""), -1)

	if err := ioutil.WriteFile("builtins.go", b, 0644); err != nil {
		log.Fatal(err)
	}
	if err != nil {
		log.Fatal(err)
	}
}

type generator struct {
	w          *bytes.Buffer
	decls      *bytes.Buffer
	name       string
	fset       *token.FileSet
	defaultPkg string
	first      bool
	iota       int

	imports []*ast.ImportSpec
}

func (g *generator) processDir(dir string) {
	goFiles, err := filepath.Glob(filepath.Join(dir, "*.go"))
	if err != nil {
		log.Fatal(err)
	}

	cueFiles, err := filepath.Glob(filepath.Join(dir, "*.cue"))
	if err != nil {
		log.Fatal(err)
	}

	if len(goFiles)+len(cueFiles) == 0 {
		return
	}

	pkg := dir[len(prefix):]
	fmt.Fprintf(g.w, "%q: &builtinPkg{\nnative: []*builtin{{\n", pkg)
	g.first = true
	for _, filename := range goFiles {
		g.processGo(filename)
	}
	fmt.Fprintf(g.w, "}},\n")
	g.processCUE(dir)
	fmt.Fprintf(g.w, "},\n")
}

func (g *generator) sep() {
	if g.first {
		g.first = false
		return
	}
	fmt.Fprintln(g.w, "}, {")
}

func importName(s *ast.ImportSpec) string {
	if s.Name != nil {
		return s.Name.Name
	}
	pkg, err := strconv.Unquote(s.Path.Value)
	if err != nil {
		log.Fatal(err)
	}
	return path.Base(pkg)
}

// processCUE mixes in CUE definitions defined in the package directory.
func (g *generator) processCUE(dir string) {
	instances := cue.Build(load.Instances([]string{dir}, &load.Config{
		StdRoot: "../pkg",
	}))

	if err := instances[0].Err; err != nil {
		if !strings.Contains(err.Error(), "no CUE files") {
			errors.Print(os.Stderr, err, nil)
			log.Fatalf("error processing %s: %v", dir, err)
		}
		return
	}

	n := instances[0].Value().Syntax(cue.Raw())
	b, err := cueformat.Node(n)
	if err != nil {
		log.Fatal(err)
	}
	b = bytes.ReplaceAll(b, []byte("\n\n"), []byte("\n"))
	// body = strings.ReplaceAll(body, "\t", "")
	// TODO: escape backtick
	fmt.Fprintf(g.w, "cue: `%s`,\n", string(b))
}

func (g *generator) processGo(filename string) {
	if strings.HasSuffix(filename, "_test.go") {
		return
	}
	f, err := parser.ParseFile(g.fset, filename, nil, parser.ParseComments)
	if err != nil {
		log.Fatal(err)
	}
	g.defaultPkg = ""
	g.name = f.Name.Name
	if g.name == "structs" {
		g.name = "struct"
	}

	for _, d := range f.Decls {
		switch x := d.(type) {
		case *ast.GenDecl:
			switch x.Tok {
			case token.CONST:
				for _, spec := range x.Specs {
					if !ast.IsExported(spec.(*ast.ValueSpec).Names[0].Name) {
						continue
					}
					g.genConst(spec.(*ast.ValueSpec))
				}
			case token.IMPORT:
				for _, s := range x.Specs {
					spec := s.(*ast.ImportSpec)
					g.imports = append(g.imports, spec)
				}
				if g.defaultPkg == "" {
					g.defaultPkg = importName(x.Specs[0].(*ast.ImportSpec))
				}
			case token.VAR:
				for _, spec := range x.Specs {
					if ast.IsExported(spec.(*ast.ValueSpec).Names[0].Name) {
						log.Fatal("gen %s: var declarations not supported", filename)
					}
				}
				printer.Fprint(g.decls, g.fset, x)
				fmt.Fprint(g.decls, "\n\n")
				continue
			case token.TYPE:
				// TODO: support type declarations.
				for _, spec := range x.Specs {
					if ast.IsExported(spec.(*ast.TypeSpec).Name.Name) {
						log.Fatal("gen %s: type declarations not supported", filename)
					}
				}
				continue
			default:
				log.Fatalf("gen %s: unexpected spec of type %s", filename, x.Tok)
			}
		case *ast.FuncDecl:
			g.genFun(x)
		}
	}
}

func (g *generator) genConst(spec *ast.ValueSpec) {
	name := spec.Names[0].Name
	value := ""
	switch v := g.toValue(spec.Values[0]); v.Kind() {
	case constant.Bool, constant.Int, constant.String:
		// TODO: convert octal numbers
		value = v.ExactString()
	case constant.Float:
		var rat big.Rat
		rat.SetString(v.ExactString())
		var float big.Float
		float.SetRat(&rat)
		value = float.Text('g', -1)
	default:
		fmt.Printf("Dropped entry %s.%s (%T: %v)\n", g.defaultPkg, name, v.Kind(), v.ExactString())
		return
	}
	g.sep()
	fmt.Fprintf(g.w, "Name: %q,\n Const: %q,\n", name, value)
}

func (g *generator) toValue(x ast.Expr) constant.Value {
	switch x := x.(type) {
	case *ast.BasicLit:
		return constant.MakeFromLiteral(x.Value, x.Kind, 0)
	case *ast.BinaryExpr:
		return constant.BinaryOp(g.toValue(x.X), x.Op, g.toValue(x.Y))
	case *ast.UnaryExpr:
		return constant.UnaryOp(x.Op, g.toValue(x.X), 0)
	default:
		log.Fatalf("%s: unsupported expression type %T: %#v", g.defaultPkg, x, x)
	}
	return constant.MakeUnknown()
}

func (g *generator) genFun(x *ast.FuncDecl) {
	if x.Body == nil {
		return
	}
	types := []string{}
	if x.Type.Results != nil {
		for _, f := range x.Type.Results.List {
			if len(f.Names) > 0 {
				for range f.Names {
					types = append(types, g.goKind(f.Type))
				}
			} else {
				types = append(types, g.goKind(f.Type))
			}
		}
	}
	if n := len(types); n != 1 && (n != 2 || types[1] != "error") {
		fmt.Printf("Dropped func %s.%s: must have one return value or a value and an error %v\n", g.defaultPkg, x.Name.Name, types)
		return
	}

	if !ast.IsExported(x.Name.Name) || x.Recv != nil {
		if strings.HasPrefix(x.Name.Name, g.name) {
			printer.Fprint(g.decls, g.fset, x)
			fmt.Fprint(g.decls, "\n\n")
		}
		return
	}

	g.sep()
	fmt.Fprintf(g.w, "Name: %q,\n", x.Name.Name)

	args := []string{}
	vals := []string{}
	kind := []string{}
	for _, f := range x.Type.Params.List {
		for _, name := range f.Names {
			typ := g.goKind(f.Type)
			argKind := g.goToCUE(f.Type)
			vals = append(vals, fmt.Sprintf("c.%s(%d)", typ, len(args)))
			args = append(args, name.Name)
			kind = append(kind, argKind)
		}
	}

	fmt.Fprintf(g.w, "Params: []kind{%s},\n", strings.Join(kind, ", "))
	result := g.goToCUE(x.Type.Results.List[0].Type)
	fmt.Fprintf(g.w, "Result: %s,\n", result)
	argList := strings.Join(args, ", ")
	valList := strings.Join(vals, ", ")
	init := ""
	if len(args) > 0 {
		init = fmt.Sprintf("%s := %s", argList, valList)
	}

	fmt.Fprintf(g.w, "Func: func(c *callCtxt) {")
	defer fmt.Fprintln(g.w, "},")
	fmt.Fprintln(g.w)
	if init != "" {
		fmt.Fprintln(g.w, init)
	}
	fmt.Fprintln(g.w, "if c.do() {")
	defer fmt.Fprintln(g.w, "}")
	if len(types) == 1 {
		fmt.Fprint(g.w, "c.ret = func() interface{} ")
	} else {
		fmt.Fprint(g.w, "c.ret, c.err = func() (interface{}, error) ")
	}
	printer.Fprint(g.w, g.fset, x.Body)
	fmt.Fprintln(g.w, "()")
}

func (g *generator) goKind(expr ast.Expr) string {
	if star, isStar := expr.(*ast.StarExpr); isStar {
		expr = star.X
	}
	w := &bytes.Buffer{}
	printer.Fprint(w, g.fset, expr)
	switch str := w.String(); str {
	case "big.Int":
		return "bigInt"
	case "big.Float":
		return "bigFloat"
	case "big.Rat":
		return "bigRat"
	case "internal.Decimal":
		return "decimal"
	case "[]*internal.Decimal":
		return "decimalList"
	case "cue.Struct":
		return "structVal"
	case "cue.Value":
		return "value"
	case "cue.List":
		return "list"
	case "[]string":
		return "strList"
	case "[]byte":
		return "bytes"
	case "[]cue.Value":
		return "list"
	case "io.Reader":
		return "reader"
	case "time.Time":
		return "string"
	default:
		return str
	}
}

func (g *generator) goToCUE(expr ast.Expr) (cueKind string) {
	// TODO: detect list and structs types for return values.
	switch k := g.goKind(expr); k {
	case "error":
		cueKind += "bottomKind"
	case "bool":
		cueKind += "boolKind"
	case "bytes", "reader":
		cueKind += "bytesKind|stringKind"
	case "string":
		cueKind += "stringKind"
	case "int", "int8", "int16", "int32", "rune", "int64",
		"uint", "byte", "uint8", "uint16", "uint32", "uint64",
		"bigInt":
		cueKind += "intKind"
	case "float64", "bigRat", "bigFloat", "decimal":
		cueKind += "numKind"
	case "list", "decimalList", "strList":
		cueKind += "listKind"
	case "structVal":
		cueKind += "structKind"
	case "value":
		// Must use callCtxt.value method for these types and resolve manually.
		cueKind += "topKind" // TODO: can be more precise
	default:
		switch {
		case strings.HasPrefix(k, "[]"):
			cueKind += "listKind"
		case strings.HasPrefix(k, "map["):
			cueKind += "structKind"
		default:
			// log.Println("Unknown type:", k)
			// Must use callCtxt.value method for these types and resolve manually.
			cueKind += "topKind" // TODO: can be more precise
		}
	}
	return cueKind
}
