// Copyright 2014 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.

package bind

import (
	"fmt"
	"go/token"
	"go/types"
	"log"
	"strings"
)

type goGen struct {
	*printer
	fset *token.FileSet
	pkg  *types.Package
	err  ErrorList
}

func (g *goGen) errorf(format string, args ...interface{}) {
	g.err = append(g.err, fmt.Errorf(format, args...))
}

const goPreamble = `// Package go_%s is an autogenerated binder stub for package %s.
//   gobind -lang=go %s
//
// File is generated by gobind. Do not edit.
package go_%s

import (
	"golang.org/x/mobile/bind/seq"
	%q
)

`

func (g *goGen) genPreamble() {
	n := g.pkg.Name()
	g.Printf(goPreamble, n, n, g.pkg.Path(), n, g.pkg.Path())
}

func (g *goGen) genFuncBody(o *types.Func, selectorLHS string) {
	sig := o.Type().(*types.Signature)
	params := sig.Params()
	for i := 0; i < params.Len(); i++ {
		p := params.At(i)
		g.genRead("param_"+paramName(params, i), "in", p.Type())
	}

	res := sig.Results()
	if res.Len() > 2 || res.Len() == 2 && !isErrorType(res.At(1).Type()) {
		g.errorf("functions and methods must return either zero or one values, and optionally an error")
		return
	}
	returnsValue := false
	returnsError := false
	if res.Len() == 1 {
		if isErrorType(res.At(0).Type()) {
			returnsError = true
			g.Printf("err := ")
		} else {
			returnsValue = true
			g.Printf("res := ")
		}
	} else if res.Len() == 2 {
		returnsValue = true
		returnsError = true
		g.Printf("res, err := ")
	}

	g.Printf("%s.%s(", selectorLHS, o.Name())
	for i := 0; i < params.Len(); i++ {
		if i > 0 {
			g.Printf(", ")
		}
		g.Printf("param_%s", paramName(params, i))
	}
	g.Printf(")\n")

	if returnsValue {
		g.genWrite("res", "out", res.At(0).Type())
	}
	if returnsError {
		g.genWrite("err", "out", res.At(res.Len()-1).Type())
	}
}

func (g *goGen) genWrite(valName, seqName string, T types.Type) {
	if isErrorType(T) {
		g.Printf("if %s == nil {\n", valName)
		g.Printf("    %s.WriteString(\"\");\n", seqName)
		g.Printf("} else {\n")
		g.Printf("    %s.WriteString(%s.Error());\n", seqName, valName)
		g.Printf("}\n")
		return
	}
	switch T := T.(type) {
	case *types.Pointer:
		// TODO(crawshaw): test *int
		// TODO(crawshaw): test **Generator
		switch T := T.Elem().(type) {
		case *types.Named:
			obj := T.Obj()
			if obj.Pkg() != g.pkg {
				g.errorf("type %s not defined in package %s", T, g.pkg)
				return
			}
			g.Printf("%s.WriteGoRef(%s)\n", seqName, valName)
		default:
			g.errorf("unsupported type %s", T)
		}
	case *types.Named:
		switch u := T.Underlying().(type) {
		case *types.Interface, *types.Pointer:
			g.Printf("%s.WriteGoRef(%s)\n", seqName, valName)
		default:
			g.errorf("unsupported, direct named type %s: %s", T, u)
		}
	default:
		g.Printf("%s.Write%s(%s);\n", seqName, seqType(T), valName)
	}
}

func (g *goGen) genFunc(o *types.Func) {
	g.Printf("func proxy_%s(out, in *seq.Buffer) {\n", o.Name())
	g.Indent()
	g.genFuncBody(o, g.pkg.Name())
	g.Outdent()
	g.Printf("}\n\n")
}

func exportedMethodSet(T types.Type) []*types.Func {
	var methods []*types.Func
	methodset := types.NewMethodSet(T)
	for i := 0; i < methodset.Len(); i++ {
		obj := methodset.At(i).Obj()
		if !obj.Exported() {
			continue
		}
		switch obj := obj.(type) {
		case *types.Func:
			methods = append(methods, obj)
		default:
			log.Panicf("unexpected methodset obj: %s", obj)
		}
	}
	return methods
}

func exportedFields(T *types.Struct) []*types.Var {
	var fields []*types.Var
	for i := 0; i < T.NumFields(); i++ {
		f := T.Field(i)
		if !f.Exported() {
			continue
		}
		fields = append(fields, f)
	}
	return fields
}

func (g *goGen) genStruct(obj *types.TypeName, T *types.Struct) {
	fields := exportedFields(T)
	methods := exportedMethodSet(types.NewPointer(obj.Type()))

	g.Printf("const (\n")
	g.Indent()
	g.Printf("proxy%s_Descriptor = \"go.%s.%s\"\n", obj.Name(), g.pkg.Name(), obj.Name())
	for i, f := range fields {
		g.Printf("proxy%s_%s_Get_Code = 0x%x0f\n", obj.Name(), f.Name(), i)
		g.Printf("proxy%s_%s_Set_Code = 0x%x1f\n", obj.Name(), f.Name(), i)
	}
	for i, m := range methods {
		g.Printf("proxy%s_%s_Code = 0x%x0c\n", obj.Name(), m.Name(), i)
	}
	g.Outdent()
	g.Printf(")\n\n")

	g.Printf("type proxy%s seq.Ref\n\n", obj.Name())

	for _, f := range fields {
		seqTyp := seqType(f.Type())

		g.Printf("func proxy%s_%s_Set(out, in *seq.Buffer) {\n", obj.Name(), f.Name())
		g.Indent()
		g.Printf("ref := in.ReadRef()\n")
		g.Printf("v := in.Read%s()\n", seqTyp)
		if seqTyp == "Ref" {
			g.Printf("ref.Get().(*%s.%s).%s = v.Get().(%s)\n", g.pkg.Name(), obj.Name(), f.Name(), g.typeString(f.Type()))
		} else {
			// TODO(crawshaw): other kinds of non-ptr types.
			g.Printf("ref.Get().(*%s.%s).%s = v\n", g.pkg.Name(), obj.Name(), f.Name())
		}
		g.Outdent()
		g.Printf("}\n\n")

		g.Printf("func proxy%s_%s_Get(out, in *seq.Buffer) {\n", obj.Name(), f.Name())
		g.Indent()
		g.Printf("ref := in.ReadRef()\n")
		g.Printf("v := ref.Get().(*%s.%s).%s\n", g.pkg.Name(), obj.Name(), f.Name())
		if seqTyp == "Ref" {
			g.Printf("out.WriteGoRef(v)\n")
		} else {
			g.Printf("out.Write%s(v)\n", seqTyp)
		}
		g.Outdent()
		g.Printf("}\n\n")
	}

	for _, m := range methods {
		g.Printf("func proxy%s_%s(out, in *seq.Buffer) {\n", obj.Name(), m.Name())
		g.Indent()
		g.Printf("ref := in.ReadRef()\n")
		g.Printf("v := ref.Get().(*%s.%s)\n", g.pkg.Name(), obj.Name())
		g.genFuncBody(m, "v")
		g.Outdent()
		g.Printf("}\n\n")
	}

	g.Printf("func init() {\n")
	g.Indent()
	for _, f := range fields {
		n := f.Name()
		g.Printf("seq.Register(proxy%s_Descriptor, proxy%s_%s_Set_Code, proxy%s_%s_Set)\n", obj.Name(), obj.Name(), n, obj.Name(), n)
		g.Printf("seq.Register(proxy%s_Descriptor, proxy%s_%s_Get_Code, proxy%s_%s_Get)\n", obj.Name(), obj.Name(), n, obj.Name(), n)
	}
	for _, m := range methods {
		n := m.Name()
		g.Printf("seq.Register(proxy%s_Descriptor, proxy%s_%s_Code, proxy%s_%s)\n", obj.Name(), obj.Name(), n, obj.Name(), n)
	}
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *goGen) genInterface(obj *types.TypeName) {
	iface := obj.Type().(*types.Named).Underlying().(*types.Interface)

	ifaceDesc := fmt.Sprintf("go.%s.%s", g.pkg.Name(), obj.Name())

	// Descriptor and code for interface methods.
	g.Printf("const (\n")
	g.Indent()
	g.Printf("proxy%s_Descriptor = %q\n", obj.Name(), ifaceDesc)
	for i := 0; i < iface.NumMethods(); i++ {
		g.Printf("proxy%s_%s_Code = 0x%x0a\n", obj.Name(), iface.Method(i).Name(), i+1)
	}
	g.Outdent()
	g.Printf(")\n\n")

	// Define the entry points.
	for i := 0; i < iface.NumMethods(); i++ {
		m := iface.Method(i)
		g.Printf("func proxy%s_%s(out, in *seq.Buffer) {\n", obj.Name(), m.Name())
		g.Indent()
		g.Printf("ref := in.ReadRef()\n")
		g.Printf("v := ref.Get().(%s.%s)\n", g.pkg.Name(), obj.Name())
		g.genFuncBody(m, "v")
		g.Outdent()
		g.Printf("}\n\n")
	}

	// Register the method entry points.
	g.Printf("func init() {\n")
	g.Indent()
	for i := 0; i < iface.NumMethods(); i++ {
		g.Printf("seq.Register(proxy%s_Descriptor, proxy%s_%s_Code, proxy%s_%s)\n",
			obj.Name(), obj.Name(), iface.Method(i).Name(), obj.Name(), iface.Method(i).Name())
	}
	g.Outdent()
	g.Printf("}\n\n")

	// Define a proxy interface.
	g.Printf("type proxy%s seq.Ref\n\n", obj.Name())

	for i := 0; i < iface.NumMethods(); i++ {
		m := iface.Method(i)
		sig := m.Type().(*types.Signature)
		params := sig.Params()
		res := sig.Results()

		if res.Len() > 2 ||
			(res.Len() == 2 && !isErrorType(res.At(1).Type())) {
			g.errorf("functions and methods must return either zero or one value, and optionally an error: %s.%s", obj.Name(), m.Name())
			continue
		}

		g.Printf("func (p *proxy%s) %s(", obj.Name(), m.Name())
		for i := 0; i < params.Len(); i++ {
			if i > 0 {
				g.Printf(", ")
			}
			g.Printf("%s %s", paramName(params, i), g.typeString(params.At(i).Type()))
		}
		g.Printf(") ")

		if res.Len() == 1 {
			g.Printf(g.typeString(res.At(0).Type()))
		} else if res.Len() == 2 {
			g.Printf("(%s, error)", g.typeString(res.At(0).Type()))
		}
		g.Printf(" {\n")
		g.Indent()

		g.Printf("in := new(seq.Buffer)\n")
		for i := 0; i < params.Len(); i++ {
			g.genWrite(paramName(params, i), "in", params.At(i).Type())
		}

		if res.Len() == 0 {
			g.Printf("seq.Transact((*seq.Ref)(p), %q, proxy%s_%s_Code, in)\n", ifaceDesc, obj.Name(), m.Name())
		} else {
			g.Printf("out := seq.Transact((*seq.Ref)(p), %q, proxy%s_%s_Code, in)\n", ifaceDesc, obj.Name(), m.Name())
			var rvs []string
			for i := 0; i < res.Len(); i++ {
				rv := fmt.Sprintf("res_%d", i)
				g.genRead(rv, "out", res.At(i).Type())
				rvs = append(rvs, rv)
			}
			g.Printf("return %s\n", strings.Join(rvs, ","))
		}

		g.Outdent()
		g.Printf("}\n\n")
	}
}

func (g *goGen) genRead(valName, seqName string, typ types.Type) {
	if isErrorType(typ) {
		g.Printf("%s := %s.ReadError()\n", valName, seqName)
		return
	}
	switch t := typ.(type) {
	case *types.Pointer:
		switch u := t.Elem().(type) {
		case *types.Named:
			o := u.Obj()
			if o.Pkg() != g.pkg {
				g.errorf("type %s not defined in package %s", u, g.pkg)
				return
			}
			g.Printf("// Must be a Go object\n")
			g.Printf("%s_ref := %s.ReadRef()\n", valName, seqName)
			g.Printf("%s := %s_ref.Get().(*%s.%s)\n", valName, valName, g.pkg.Name(), o.Name())
		default:
			g.errorf("unsupported type %s", t)
		}
	case *types.Named:
		switch t.Underlying().(type) {
		case *types.Interface, *types.Pointer:
			o := t.Obj()
			if o.Pkg() != g.pkg {
				g.errorf("type %s not defined in package %s", t, g.pkg)
				return
			}
			g.Printf("var %s %s\n", valName, g.typeString(t))
			g.Printf("%s_ref := %s.ReadRef()\n", valName, seqName)
			g.Printf("if %s_ref.Num < 0 { // go object \n", valName)
			g.Printf("   %s = %s_ref.Get().(%s.%s)\n", valName, valName, g.pkg.Name(), o.Name())
			g.Printf("} else {  // foreign object \n")
			g.Printf("   %s = (*proxy%s)(%s_ref)\n", valName, o.Name(), valName)
			g.Printf("}\n")
		}
	default:
		g.Printf("%s := %s.Read%s()\n", valName, seqName, seqType(t))
	}
}

func (g *goGen) typeString(typ types.Type) string {
	pkg := g.pkg

	switch t := typ.(type) {
	case *types.Named:
		obj := t.Obj()
		if obj.Pkg() == nil { // e.g. error type is *types.Named.
			return types.TypeString(typ, types.RelativeTo(pkg))
		}
		if obj.Pkg() != g.pkg {
			g.errorf("type %s not defined in package %s", t, g.pkg)
		}

		switch t.Underlying().(type) {
		case *types.Interface, *types.Struct:
			return fmt.Sprintf("%s.%s", pkg.Name(), types.TypeString(typ, types.RelativeTo(pkg)))
		default:
			g.errorf("unsupported named type %s / %T", t, t)
		}
	case *types.Pointer:
		switch t := t.Elem().(type) {
		case *types.Named:
			return fmt.Sprintf("*%s", g.typeString(t))
		default:
			g.errorf("not yet supported, pointer type %s / %T", t, t)
		}
	default:
		return types.TypeString(typ, types.RelativeTo(pkg))
	}
	return ""
}

func (g *goGen) gen() error {
	g.genPreamble()

	var funcs []string

	scope := g.pkg.Scope()
	names := scope.Names()
	for _, name := range names {
		obj := scope.Lookup(name)
		if !obj.Exported() {
			continue
		}

		switch obj := obj.(type) {
		// TODO(crawshaw): case *types.Const:
		// TODO(crawshaw): case *types.Var:
		case *types.Func:
			g.genFunc(obj)
			funcs = append(funcs, obj.Name())
		case *types.TypeName:
			named := obj.Type().(*types.Named)
			switch T := named.Underlying().(type) {
			case *types.Struct:
				g.genStruct(obj, T)
			case *types.Interface:
				g.genInterface(obj)
			}

		default:
			g.errorf("not yet supported, name for %v / %T", obj, obj)
			continue
		}
	}

	g.Printf("func init() {\n")
	g.Indent()
	for i, name := range funcs {
		g.Printf("seq.Register(%q, %d, proxy_%s)\n", g.pkg.Name(), i+1, name)
	}
	g.Outdent()
	g.Printf("}\n")

	if len(g.err) > 0 {
		return g.err
	}
	return nil
}
