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

package bind

import (
	"fmt"
	"path/filepath"
	"strings"
	"unicode"
	"unicode/utf8"

	"golang.org/x/mobile/internal/importers/java"
)

type (
	// ClassGen generates Go and C stubs for Java classes so import statements
	// on the form
	//
	//
	// import "Java/classpath/to/Class"
	//
	// will work.
	ClassGen struct {
		*Printer
		imported map[string]struct{}
		// The list of imported Java classes
		classes []*java.Class
		// The list of Go package paths with Java interfaces inside
		jpkgs []string
		// For each Go package path, the list of Java classes.
		typePkgs map[string][]*java.Class
		// For each Go package path, the Java class with static functions
		// or constants.
		clsPkgs map[string]*java.Class
	}
)

func (g *ClassGen) isSupported(t *java.Type) bool {
	switch t.Kind {
	case java.Array:
		// TODO: Support all array types
		return t.Elem.Kind == java.Byte
	default:
		return true
	}
}

func (g *ClassGen) isFuncSupported(f *java.Func) bool {
	for _, a := range f.Params {
		if !g.isSupported(a) {
			return false
		}
	}
	if f.Ret != nil {
		return g.isSupported(f.Ret)
	}
	return true
}

func (g *ClassGen) goType(t *java.Type, local bool) string {
	switch t.Kind {
	case java.Int:
		return "int32"
	case java.Boolean:
		return "bool"
	case java.Short:
		return "int16"
	case java.Char:
		return "uint16"
	case java.Byte:
		return "byte"
	case java.Long:
		return "int64"
	case java.Float:
		return "float32"
	case java.Double:
		return "float64"
	case java.String:
		return "string"
	case java.Array:
		return "[]" + g.goType(t.Elem, local)
	case java.Object:
		if _, exists := g.imported[t.Class]; !exists {
			return "interface{}"
		}
		name := goClsName(t.Class)
		if !local {
			name = "Java." + name
		}
		return name
	default:
		panic("invalid kind")
	}
}

func (g *ClassGen) Init(classes []*java.Class) {
	g.classes = classes
	g.imported = make(map[string]struct{})
	g.typePkgs = make(map[string][]*java.Class)
	g.clsPkgs = make(map[string]*java.Class)
	pkgSet := make(map[string]struct{})
	for _, cls := range classes {
		g.imported[cls.Name] = struct{}{}
		clsPkg := strings.Replace(cls.Name, ".", "/", -1)
		g.clsPkgs[clsPkg] = cls
		typePkg := filepath.Dir(clsPkg)
		g.typePkgs[typePkg] = append(g.typePkgs[typePkg], cls)
		if _, exists := pkgSet[clsPkg]; !exists {
			pkgSet[clsPkg] = struct{}{}
			g.jpkgs = append(g.jpkgs, clsPkg)
		}
		if _, exists := pkgSet[typePkg]; !exists {
			pkgSet[typePkg] = struct{}{}
			g.jpkgs = append(g.jpkgs, typePkg)
		}
	}
}

// Packages return the list of Go packages to be generated.
func (g *ClassGen) Packages() []string {
	return g.jpkgs
}

func (g *ClassGen) GenPackage(idx int) {
	jpkg := g.jpkgs[idx]
	g.Printf("// File is generated by gobind. Do not edit.\n\n")
	g.Printf("package %s\n\n", filepath.Base(jpkg))
	g.Printf("import \"Java\"\n\n")
	g.Printf("const _ = Java.Dummy\n\n")
	for _, cls := range g.typePkgs[jpkg] {
		g.Printf("type %s Java.%s\n", cls.PkgName, goClsName(cls.Name))
	}
	if cls, ok := g.clsPkgs[jpkg]; ok {
		g.Printf("const (\n")
		g.Indent()
		// Constants
		for _, v := range cls.Vars {
			if g.isSupported(v.Type) && v.Constant() {
				g.Printf("%s = %s\n", initialUpper(v.Name), v.Val)
			}
		}
		g.Outdent()
		g.Printf(")\n\n")

		g.Printf("var (\n")
		g.Indent()
		// Functions
		for _, f := range cls.Funcs {
			if !f.Public || !g.isFuncSupported(f) {
				continue
			}
			g.Printf("%s func", f.GoName)
			g.genFuncDecl(false, f)
			g.Printf("\n")
		}
		g.Outdent()
		g.Printf(")\n\n")
	}
}

func (g *ClassGen) GenGo() {
	g.Printf(classesGoHeader)
	for _, cls := range g.classes {
		for _, f := range cls.Funcs {
			if f.Public && g.isFuncSupported(f) {
				pkgName := strings.Replace(cls.Name, ".", "/", -1)
				g.Printf("import %q\n", "Java/"+pkgName)
				break
			}
		}
	}
	if len(g.classes) > 0 {
		g.Printf("import \"unsafe\"\n\n")
	}
	g.Printf("type proxy interface { Bind_proxy_refnum__() int32 }\n\n")
	g.Printf("// Suppress unused package error\n\n")
	g.Printf("var _ = _seq.FromRefNum\n")
	g.Printf("const _ = Java.Dummy\n\n")
	g.Printf("//export initClasses\n")
	g.Printf("func initClasses() {\n")
	g.Indent()
	g.Printf("C.init_proxies()\n")
	for _, cls := range g.classes {
		g.Printf("init_%s()\n", cls.JNIName)
	}
	g.Outdent()
	g.Printf("}\n\n")
	for _, cls := range g.classes {
		g.genGo(cls)
	}
}

func (g *ClassGen) GenH() {
	g.Printf(classesHHeader)
	for _, tn := range []string{"jint", "jboolean", "jshort", "jchar", "jbyte", "jlong", "jfloat", "jdouble", "nstring", "nbyteslice"} {
		g.Printf("typedef struct ret_%s {\n", tn)
		g.Printf("	%s res;\n", tn)
		g.Printf("	jint exc;\n")
		g.Printf("} ret_%s;\n", tn)
	}
	g.Printf("\n")
	for _, cls := range g.classes {
		for _, f := range cls.AllMethods {
			if !g.isFuncSupported(f) {
				continue
			}
			g.Printf("extern ")
			g.genCMethodDecl("cproxy", cls.JNIName, f)
			g.Printf(";\n")
			if cls.HasSuper() {
				g.Printf("extern ")
				g.genCMethodDecl("csuper", cls.JNIName, f)
				g.Printf(";\n")
			}
		}
	}
	for _, cls := range g.classes {
		g.genH(cls)
	}
}

func (g *ClassGen) GenC() {
	g.Printf(classesCHeader)
	for _, cls := range g.classes {
		g.genC(cls)
		g.Printf("static jclass class_%s;\n", cls.JNIName)
		for _, f := range cls.AllMethods {
			if g.isFuncSupported(f) {
				g.Printf("static jmethodID m_%s_%s;\n", cls.JNIName, f.JNIName)
			}
		}
	}
	g.Printf("\n")
	g.Printf("void init_proxies() {\n")
	g.Indent()
	g.Printf("JNIEnv *env = go_seq_push_local_frame(%d);\n", len(g.classes))
	g.Printf("jclass clazz;\n")
	for _, cls := range g.classes {
		g.Printf("clazz = (*env)->FindClass(env, %q);\n", strings.Replace(cls.FindName, ".", "/", -1))
		g.Printf("class_%s = (*env)->NewGlobalRef(env, clazz);\n", cls.JNIName)
		for _, f := range cls.AllMethods {
			if g.isFuncSupported(f) {
				g.Printf("m_%s_%s = go_seq_get_method_id(clazz, %q, %q);\n", cls.JNIName, f.JNIName, f.Name, f.Desc)
			}
		}
	}
	g.Printf("go_seq_pop_local_frame(env);\n")
	g.Outdent()
	g.Printf("}\n\n")
	for _, cls := range g.classes {
		for _, f := range cls.AllMethods {
			if !g.isFuncSupported(f) {
				continue
			}
			g.genCMethodDecl("cproxy", cls.JNIName, f)
			g.genCMethodBody(cls, f, false)
			if cls.HasSuper() {
				g.genCMethodDecl("csuper", cls.JNIName, f)
				g.genCMethodBody(cls, f, true)
			}
		}
	}
}

func (g *ClassGen) GenInterfaces() {
	g.Printf(classesPkgHeader)
	for _, cls := range g.classes {
		g.genInterface(cls)
	}
}

func (g *ClassGen) genCMethodBody(cls *java.Class, f *java.Func, virtual bool) {
	g.Printf(" {\n")
	g.Indent()
	// Add 1 for the 'this' argument
	g.Printf("JNIEnv *env = go_seq_push_local_frame(%d);\n", len(f.Params)+1)
	g.Printf("// Must be a Java object\n")
	g.Printf("jobject _this = go_seq_from_refnum(env, this, NULL, NULL);\n")
	for i, a := range f.Params {
		g.genCToJava(fmt.Sprintf("a%d", i), a)
	}
	if f.Ret != nil {
		g.Printf("%s res = ", f.Ret.JNIType())
	}
	g.Printf("(*env)->Call")
	if virtual {
		g.Printf("Nonvirtual")
	}
	if f.Ret != nil {
		g.Printf(f.Ret.JNICallType())
	} else {
		g.Printf("Void")
	}
	g.Printf("Method(env, _this, ")
	if virtual {
		g.Printf("class_%s, ", cls.JNIName)
	}
	g.Printf("m_%s_%s", cls.JNIName, f.JNIName)
	for i := range f.Params {
		g.Printf(", _a%d", i)
	}
	g.Printf(");\n")
	g.Printf("jobject _exc = go_seq_wrap_exception(env);\n")
	g.Printf("int32_t _exc_ref = go_seq_to_refnum(env, _exc);\n")
	if f.Ret != nil {
		g.genJavaToC("res", f.Ret)
	}
	g.Printf("go_seq_pop_local_frame(env);\n")
	if f.Ret != nil {
		g.Printf("ret_%s __res = {_res, _exc_ref};\n", f.Ret.CType())
		g.Printf("return __res;\n")
	} else {
		g.Printf("return _exc_ref;\n")
	}
	g.Outdent()
	g.Printf("}\n\n")
}

func initialUpper(s string) string {
	if s == "" {
		return ""
	}
	r, n := utf8.DecodeRuneInString(s)
	return string(unicode.ToUpper(r)) + s[n:]
}

func (g *ClassGen) genFuncDecl(local bool, f *java.Func) {
	g.Printf("(")
	for i, a := range f.Params {
		if i > 0 {
			g.Printf(", ")
		}
		g.Printf("a%d %s", i, g.goType(a, local))
	}
	g.Printf(")")
	if f.Throws != "" {
		if f.Ret != nil {
			g.Printf(" (%s, error)", g.goType(f.Ret, local))
		} else {
			g.Printf(" error")
		}
	} else if f.Ret != nil {
		g.Printf(" %s", g.goType(f.Ret, local))
	}
}

func (g *ClassGen) genC(cls *java.Class) {
	for _, f := range cls.Funcs {
		if !f.Public || !g.isFuncSupported(f) {
			continue
		}
		g.genCFuncDecl(cls.JNIName, f)
		g.Printf(" {\n")
		g.Indent()
		g.Printf("JNIEnv *env = go_seq_push_local_frame(%d);\n", len(f.Params))
		for i, a := range f.Params {
			g.genCToJava(fmt.Sprintf("a%d", i), a)
		}
		if f.Constructor {
			g.Printf("jobject res = (*env)->NewObject(env")
		} else if f.Ret != nil {
			g.Printf("%s res = (*env)->CallStatic%sMethod(env", f.Ret.JNIType(), f.Ret.JNICallType())
		} else {
			g.Printf("(*env)->CallStaticVoidMethod(env")
		}
		g.Printf(", clazz, m")
		for i := range f.Params {
			g.Printf(", _a%d", i)
		}
		g.Printf(");\n")
		g.Printf("jobject _exc = go_seq_wrap_exception(env);\n")
		g.Printf("int32_t _exc_ref = go_seq_to_refnum(env, _exc);\n")
		if f.Ret != nil {
			g.genJavaToC("res", f.Ret)
		}
		g.Printf("go_seq_pop_local_frame(env);\n")
		if f.Ret != nil {
			g.Printf("ret_%s __res = {_res, _exc_ref};\n", f.Ret.CType())
			g.Printf("return __res;\n")
		} else {
			g.Printf("return _exc_ref;\n")
		}
		g.Outdent()
		g.Printf("}\n\n")
	}
}

func (g *ClassGen) genH(cls *java.Class) {
	for _, f := range cls.Funcs {
		if !f.Public || !g.isFuncSupported(f) {
			continue
		}
		g.Printf("extern ")
		g.genCFuncDecl(cls.JNIName, f)
		g.Printf(";\n")
	}
}

func (g *ClassGen) genCMethodDecl(prefix, jniName string, f *java.Func) {
	if f.Ret != nil {
		g.Printf("ret_%s", f.Ret.CType())
	} else {
		// Return only the exception, if any
		g.Printf("jint")
	}
	g.Printf(" %s_%s_%s(jint this", prefix, jniName, f.JNIName)
	for i, a := range f.Params {
		g.Printf(", %s a%d", a.CType(), i)
	}
	g.Printf(")")
}

func (g *ClassGen) genCFuncDecl(jniName string, f *java.Func) {
	if f.Ret != nil {
		g.Printf("ret_%s", f.Ret.CType())
	} else {
		// Return only the exception, if any
		g.Printf("jint")
	}
	g.Printf(" cproxy_s_%s_%s(jclass clazz, jmethodID m", jniName, f.JNIName)
	for i, a := range f.Params {
		g.Printf(", %s a%d", a.CType(), i)
	}
	g.Printf(")")
}

func (g *ClassGen) genGo(cls *java.Class) {
	g.Printf("func init_%s() {\n", cls.JNIName)
	g.Indent()
	g.Printf("cls := C.CString(%q)\n", strings.Replace(cls.FindName, ".", "/", -1))
	g.Printf("clazz := C.go_seq_find_class(cls)\n")
	g.Printf("C.free(unsafe.Pointer(cls))\n")
	g.Printf("if clazz == nil {\n")
	g.Printf("	return\n")
	g.Printf("}\n")
	for _, f := range cls.Funcs {
		if !f.Public || !g.isFuncSupported(f) {
			continue
		}
		g.Printf("{\n")
		g.Indent()
		name := f.Name
		if f.Constructor {
			name = "<init>"
		}
		g.Printf("fn := C.CString(%q)\n", name)
		g.Printf("fd := C.CString(%q)\n", f.Desc)
		if f.Constructor {
			g.Printf("m := C.go_seq_get_method_id(clazz, fn, fd)\n")
		} else {
			g.Printf("m := C.go_seq_get_static_method_id(clazz, fn, fd)\n")
		}
		g.Printf("C.free(unsafe.Pointer(fn))\n")
		g.Printf("C.free(unsafe.Pointer(fd))\n")
		g.Printf("if m != nil {\n")
		g.Indent()
		g.Printf("%s.%s = func", cls.PkgName, f.GoName)
		g.genFuncDecl(false, f)
		g.Printf(" {\n")
		g.Indent()
		for i, a := range f.Params {
			g.genWrite(fmt.Sprintf("a%d", i), a, modeTransient)
		}
		g.Printf("res := C.cproxy_s_%s_%s(clazz, m", cls.JNIName, f.JNIName)
		for i := range f.Params {
			g.Printf(", _a%d", i)
		}
		g.Printf(")\n")
		g.genFuncRet(f)
		g.Outdent()
		g.Printf("}\n")
		g.Outdent()
		g.Printf("}\n")
		g.Outdent()
		g.Printf("}\n")
	}
	g.Outdent()
	g.Printf("}\n\n")
	g.Printf("type proxy_class_%s _seq.Ref\n\n", cls.JNIName)
	g.Printf("func (p *proxy_class_%s) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }\n\n", cls.JNIName)
	for _, f := range cls.AllMethods {
		if !g.isFuncSupported(f) {
			continue
		}
		g.Printf("func (p *proxy_class_%s) %s", cls.JNIName, f.GoName)
		g.genFuncDecl(false, f)
		g.genFuncBody(cls, f, "cproxy")
	}
	if cls.Throwable {
		g.Printf("func (p *proxy_class_%s) Error() string {\n", cls.JNIName)
		g.Printf("	return p.ToString()\n")
		g.Printf("}\n")
	}
	if cls.HasSuper() {
		g.Printf("func (p *proxy_class_%s) Super() Java.%s {\n", cls.JNIName, goClsName(cls.Name))
		g.Printf("	return &super_%s{p}\n", cls.JNIName)
		g.Printf("}\n\n")
		g.Printf("type super_%s struct {*proxy_class_%[1]s}\n\n", cls.JNIName)
		for _, f := range cls.AllMethods {
			if !g.isFuncSupported(f) {
				continue
			}
			g.Printf("func (p *super_%s) %s", cls.JNIName, f.GoName)
			g.genFuncDecl(false, f)
			g.genFuncBody(cls, f, "csuper")
		}
	}
}

func (g *ClassGen) genFuncBody(cls *java.Class, f *java.Func, prefix string) {
	g.Printf(" {\n")
	g.Indent()
	for i, a := range f.Params {
		g.genWrite(fmt.Sprintf("a%d", i), a, modeTransient)
	}
	g.Printf("res := C.%s_%s_%s(C.jint(p.Bind_proxy_refnum__())", prefix, cls.JNIName, f.JNIName)
	for i := range f.Params {
		g.Printf(", _a%d", i)
	}
	g.Printf(")\n")
	g.genFuncRet(f)
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *ClassGen) genFuncRet(f *java.Func) {
	if f.Ret != nil {
		g.genRead("_res", "res.res", f.Ret, modeRetained)
		g.genRefRead("_exc", "res.exc", "error", "proxy_error", true)
	} else {
		g.genRefRead("_exc", "res", "error", "proxy_error", true)
	}
	if f.Throws == "" {
		g.Printf("if (_exc != nil) { panic(_exc) }\n")
		if f.Ret != nil {
			g.Printf("return _res\n")
		}
	} else {
		if f.Ret != nil {
			g.Printf("return _res, _exc\n")
		} else {
			g.Printf("return _exc\n")
		}
	}
}

func (g *ClassGen) genRead(to, from string, t *java.Type, mode varMode) {
	switch t.Kind {
	case java.Int, java.Short, java.Char, java.Byte, java.Long, java.Float, java.Double:
		g.Printf("%s := %s(%s)\n", to, g.goType(t, false), from)
	case java.Boolean:
		g.Printf("%s := %s != C.JNI_FALSE\n", to, from)
	case java.String:
		g.Printf("%s := decodeString(%s)\n", to, from)
	case java.Array:
		if t.Elem.Kind != java.Byte {
			panic("unsupported array type")
		}
		g.Printf("%s := toSlice(%s, %v)\n", to, from, mode == modeRetained)
	case java.Object:
		_, hasProxy := g.imported[t.Class]
		g.genRefRead(to, from, g.goType(t, false), "proxy_class_"+flattenName(t.Class), hasProxy)
	default:
		panic("invalid kind")
	}
}

func (g *ClassGen) genRefRead(to, from string, intfName, proxyName string, hasProxy bool) {
	g.Printf("var %s %s\n", to, intfName)
	g.Printf("%s_ref := _seq.FromRefNum(int32(%s))\n", to, from)
	g.Printf("if %s_ref != nil {\n", to)
	g.Printf("	if %s < 0 { // go object\n", from)
	g.Printf("		%s = %s_ref.Get().(%s)\n", to, to, intfName)
	if hasProxy {
		g.Printf("	} else { // foreign object\n")
		g.Printf("		%s = (*%s)(%s_ref)\n", to, proxyName, to)
	}
	g.Printf("	}\n")
	g.Printf("}\n")
}

func (g *ClassGen) genWrite(v string, t *java.Type, mode varMode) {
	switch t.Kind {
	case java.Int, java.Short, java.Char, java.Byte, java.Long, java.Float, java.Double:
		g.Printf("_%s := C.%s(%s)\n", v, t.CType(), v)
	case java.Boolean:
		g.Printf("_%s := C.jboolean(C.JNI_FALSE)\n", v)
		g.Printf("if %s {\n", v)
		g.Printf("	_%s = C.jboolean(C.JNI_TRUE)\n", v)
		g.Printf("}\n")
	case java.String:
		g.Printf("_%s := encodeString(%s)\n", v, v)
	case java.Array:
		if t.Elem.Kind != java.Byte {
			panic("unsupported array type")
		}
		g.Printf("_%s := fromSlice(%s, %v)\n", v, v, mode == modeRetained)
	case java.Object:
		g.Printf("var _%s C.jint = _seq.NullRefNum\n", v)
		g.Printf("if %s != nil {\n", v)
		g.Printf("	_%s = C.jint(_seq.ToRefNum(%s))\n", v, v)
		g.Printf("}\n")
	default:
		panic("invalid kind")
	}
}

func (g *ClassGen) genJavaToC(v string, t *java.Type) {
	switch t.Kind {
	case java.Int, java.Short, java.Char, java.Byte, java.Long, java.Float, java.Double, java.Boolean:
		g.Printf("%s _%s = %s;\n", t.JNIType(), v, v)
	case java.String:
		g.Printf("nstring _%s = go_seq_from_java_string(env, %s);\n", v, v)
	case java.Array:
		if t.Elem.Kind != java.Byte {
			panic("unsupported array type")
		}
		g.Printf("nbyteslice _%s = go_seq_from_java_bytearray(env, %s, 1);\n", v, v)
	case java.Object:
		g.Printf("jint _%s = go_seq_to_refnum(env, %s);\n", v, v)
	default:
		panic("invalid kind")
	}
}

func (g *ClassGen) genCToJava(v string, t *java.Type) {
	switch t.Kind {
	case java.Int, java.Short, java.Char, java.Byte, java.Long, java.Float, java.Double, java.Boolean:
		g.Printf("%s _%s = %s;\n", t.JNIType(), v, v)
	case java.String:
		g.Printf("jstring _%s = go_seq_to_java_string(env, %s);\n", v, v)
	case java.Array:
		if t.Elem.Kind != java.Byte {
			panic("unsupported array type")
		}
		g.Printf("jbyteArray _%s = go_seq_to_java_bytearray(env, %s, 0);\n", v, v)
	case java.Object:
		g.Printf("jobject _%s = go_seq_from_refnum(env, %s, NULL, NULL);\n", v, v)
	default:
		panic("invalid kind")
	}
}

func goClsName(n string) string {
	return initialUpper(strings.Replace(n, ".", "_", -1))
}

func (g *ClassGen) genInterface(cls *java.Class) {
	g.Printf("type %s interface {\n", goClsName(cls.Name))
	g.Indent()
	// Methods
	for _, f := range cls.AllMethods {
		if !g.isFuncSupported(f) {
			continue
		}
		g.Printf(f.GoName)
		g.genFuncDecl(true, f)
		g.Printf("\n")
	}
	if cls.HasSuper() {
		g.Printf("Super() %s\n", goClsName(cls.Name))
	}
	if cls.Throwable {
		g.Printf("Error() string\n")
	}
	g.Outdent()
	g.Printf("}\n\n")
}

// Flatten java class names. "java.package.Class$Inner" is converted to
// "java_package_Class_Inner"
func flattenName(n string) string {
	return strings.Replace(strings.Replace(n, ".", "_", -1), "$", "_", -1)
}

var (
	classesPkgHeader = `// File is generated by gobind. Do not edit.

package Java

// Used to silence this package not used errors
const Dummy = 0

`
	classesCHeader = `// File is generated by gobind. Do not edit.

#include <jni.h>
#include "seq.h"
#include "classes.h"

`
	classesHHeader = `// File is generated by gobind. Do not edit.

#include <jni.h>
#include "seq.h"

extern void init_proxies();

`

	javaImplHeader = `// File is generated by gobind. Do not edit.

`

	classesGoHeader = `// File is generated by gobind. Do not edit.

package gomobile_bind

/*
#include <stdlib.h> // for free()
#include <jni.h>
#include "seq.h"
#include "classes.h"
*/
import "C"

import (
	"Java"
	_seq "golang.org/x/mobile/bind/seq"
)

`
)
