// 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"
	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") {
			log.Fatal(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{}
	omitCheck := true
	for _, f := range x.Type.Params.List {
		for _, name := range f.Names {
			typ := g.goKind(f.Type)
			argKind, ground := g.goToCUE(f.Type)
			if !ground {
				omitCheck = false
			}
			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)
	}
	if !omitCheck {
		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, omitCheck bool) {
	// TODO: detect list and structs types for return values.
	omitCheck = true
	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":
		cueKind += "listKind"
	case "decimalList":
		omitCheck = false
		cueKind += "listKind"
	case "strList":
		omitCheck = false
		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
			omitCheck = false
		}
	}
	return cueKind, omitCheck
}
