// Copyright 2015 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/constant"
	"go/types"
	"math"
	"strings"
)

// TODO(hyangah): handle method name conflicts.
//   - struct with SetF method and exported F field.
//   - method names conflicting with NSObject methods. e.g. Init
//   - interface type with InitWithRef.

// TODO(hyangah): error code/domain propagation

type objcGen struct {
	prefix string // prefix arg passed by flag.

	// fields set by init.
	namePrefix string

	*Generator
}

func (g *objcGen) init() {
	g.Generator.Init()
	g.namePrefix = g.namePrefixOf(g.Pkg)
}

func (g *objcGen) namePrefixOf(pkg *types.Package) string {
	if pkg == nil {
		return "GoUniverse"
	}
	p := g.prefix
	if p == "" {
		p = "Go"
	}
	return p + strings.Title(pkg.Name())
}

func (g *objcGen) genGoH() error {
	var pkgPath string
	if g.Pkg != nil {
		pkgPath = g.Pkg.Path()
	}
	g.Printf(objcPreamble, pkgPath, g.gobindOpts(), pkgPath)
	g.Printf("#ifndef __%s_H__\n", g.pkgName)
	g.Printf("#define __%s_H__\n\n", g.pkgName)
	g.Printf("#include <stdint.h>\n")
	g.Printf("#include <objc/objc.h>\n")

	for _, i := range g.interfaces {
		if !i.summary.implementable {
			continue
		}
		for _, m := range i.summary.callable {
			if !g.isSigSupported(m.Type()) {
				g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", i.obj.Name(), m.Name())
				continue
			}
			g.genInterfaceMethodSignature(m, i.obj.Name(), true)
			g.Printf("\n")
		}
	}

	g.Printf("#endif\n")

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

func (g *objcGen) genH() error {
	var pkgPath string
	if g.Pkg != nil {
		pkgPath = g.Pkg.Path()
	}
	g.Printf(objcPreamble, pkgPath, g.gobindOpts(), pkgPath)
	g.Printf("#ifndef __%s_H__\n", g.namePrefix)
	g.Printf("#define __%s_H__\n", g.namePrefix)
	g.Printf("\n")
	g.Printf("#include <Foundation/Foundation.h>\n")
	g.Printf("#include \"GoUniverse.h\"\n")
	if g.Pkg != nil {
		for _, pkg := range g.Pkg.Imports() {
			if g.validPkg(pkg) {
				g.Printf("#include %q\n", g.namePrefixOf(pkg)+".h")
			}
		}
	}
	g.Printf("\n")

	// Forward declaration of @class and @protocol
	for _, s := range g.structs {
		g.Printf("@class %s%s;\n", g.namePrefix, s.obj.Name())
	}
	for _, i := range g.interfaces {
		g.Printf("@protocol %s%s;\n", g.namePrefix, i.obj.Name())
		if i.summary.implementable {
			g.Printf("@class %s%s;\n", g.namePrefix, i.obj.Name())
			// Forward declaration for other cases will be handled at the beginning of genM.
		}
	}
	if len(g.structs) > 0 || len(g.interfaces) > 0 {
		g.Printf("\n")
	}

	// @interfaces
	for _, s := range g.structs {
		g.genStructH(s.obj, s.t)
		g.Printf("\n")
	}
	for _, i := range g.interfaces {
		g.genInterfaceH(i.obj, i.t)
		g.Printf("\n")
	}

	// const
	// TODO: prefix with k?, or use a class method?
	for _, obj := range g.constants {
		if _, ok := obj.Type().(*types.Basic); !ok {
			g.Printf("// skipped const %s with unsupported type: %T\n\n", obj.Name(), obj)
			continue
		}
		switch b := obj.Type().(*types.Basic); b.Kind() {
		case types.String, types.UntypedString:
			g.Printf("FOUNDATION_EXPORT NSString* const %s%s;\n", g.namePrefix, obj.Name())
		default:
			g.Printf("FOUNDATION_EXPORT const %s %s%s;\n", g.objcType(obj.Type()), g.namePrefix, obj.Name())
		}
	}
	if len(g.constants) > 0 {
		g.Printf("\n")
	}

	// var
	if len(g.vars) > 0 {
		g.Printf("@interface %s : NSObject\n", g.namePrefix)
		for _, obj := range g.vars {
			if t := obj.Type(); !g.isSupported(t) {
				g.Printf("// skipped variable %s with unsupported type: %T\n\n", obj.Name(), t)
				continue
			}
			objcType := g.objcType(obj.Type())
			g.Printf("+ (%s) %s;\n", objcType, objcNameReplacer(lowerFirst(obj.Name())))
			g.Printf("+ (void) set%s:(%s)v;\n", obj.Name(), objcType)
			g.Printf("\n")
		}
		g.Printf("@end\n\n")
	}

	// static functions.
	for _, obj := range g.funcs {
		g.genFuncH(obj)
		g.Printf("\n")
	}

	for _, i := range g.interfaces {
		if i.summary.implementable {
			g.Printf("@class %s%s;\n\n", g.namePrefix, i.obj.Name())
		}
	}
	for _, i := range g.interfaces {
		if i.summary.implementable {
			// @interface Interface -- similar to what genStructH does.
			g.genInterfaceInterface(i.obj, i.summary, true)
			g.Printf("\n")
		}
	}

	g.Printf("#endif\n")

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

func (g *objcGen) gobindOpts() string {
	opts := []string{"-lang=objc"}
	if g.prefix != "" {
		opts = append(opts, "-prefix="+g.prefix)
	}
	return strings.Join(opts, " ")
}

func (g *objcGen) genM() error {
	var pkgPath string
	if g.Pkg != nil {
		pkgPath = g.Pkg.Path()
	}
	g.Printf(objcPreamble, pkgPath, g.gobindOpts(), pkgPath)
	g.Printf("#include <Foundation/Foundation.h>\n")
	g.Printf("#include \"seq.h\"\n")
	g.Printf("#include \"_cgo_export.h\"\n")
	g.Printf("#include %q\n", g.namePrefix+".h")
	g.Printf("\n")

	// struct
	for _, s := range g.structs {
		g.genStructM(s.obj, s.t)
		g.Printf("\n")
	}

	// interface
	var needProxy []*types.TypeName
	for _, i := range g.interfaces {
		if g.genInterfaceM(i.obj, i.t) {
			needProxy = append(needProxy, i.obj)
		}
		g.Printf("\n")
	}

	// const
	for _, o := range g.constants {
		g.genConstM(o)
	}
	if len(g.constants) > 0 {
		g.Printf("\n")
	}

	// vars
	if len(g.vars) > 0 {
		g.Printf("@implementation %s\n", g.namePrefix)
		for _, o := range g.vars {
			g.genVarM(o)
		}
		g.Printf("@end\n\n")
	}

	g.Printf("\n")

	for _, obj := range g.funcs {
		if !g.isSigSupported(obj.Type()) {
			g.Printf("// skipped function %s with unsupported parameter or return types\n\n", obj.Name())
			continue
		}
		g.genFuncM(obj)
		g.Printf("\n")
	}

	for _, i := range g.interfaces {
		for _, m := range i.summary.callable {
			if !g.isSigSupported(m.Type()) {
				g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", i.obj.Name(), m.Name())
				continue
			}
			g.genInterfaceMethodProxy(i.obj, m)
		}
	}

	g.Printf("__attribute__((constructor)) static void init() {\n")
	g.Indent()
	g.Printf("init_seq();\n")
	g.Outdent()
	g.Printf("}\n")

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

	return nil
}

func (g *objcGen) genVarM(o *types.Var) {
	if t := o.Type(); !g.isSupported(t) {
		g.Printf("// skipped variable %s with unsupported type: %T\n\n", o.Name(), t)
		return
	}
	objcType := g.objcType(o.Type())

	// setter
	g.Printf("+ (void) set%s:(%s)v {\n", o.Name(), objcType)
	g.Indent()
	g.genWrite("v", o.Type(), modeRetained)
	g.Printf("var_set%s_%s(_v);\n", g.pkgPrefix, o.Name())
	g.genRelease("v", o.Type(), modeRetained)
	g.Outdent()
	g.Printf("}\n\n")

	// getter
	g.Printf("+ (%s) %s {\n", objcType, objcNameReplacer(lowerFirst(o.Name())))
	g.Indent()
	g.Printf("%s r0 = ", g.cgoType(o.Type()))
	g.Printf("var_get%s_%s();\n", g.pkgPrefix, o.Name())
	g.genRead("_r0", "r0", o.Type(), modeRetained)
	g.Printf("return _r0;\n")
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *objcGen) genConstM(o *types.Const) {
	if _, ok := o.Type().(*types.Basic); !ok {
		g.Printf("// skipped const %s with unsupported type: %T\n\n", o.Name(), o)
		return
	}
	cName := fmt.Sprintf("%s%s", g.namePrefix, o.Name())
	objcType := g.objcType(o.Type())

	switch b := o.Type().(*types.Basic); b.Kind() {
	case types.Bool, types.UntypedBool:
		v := "NO"
		if constant.BoolVal(o.Val()) {
			v = "YES"
		}
		g.Printf("const BOOL %s = %s;\n", cName, v)

	case types.String, types.UntypedString:
		g.Printf("NSString* const %s = @%s;\n", cName, constExactString(o))

	case types.Int, types.Int8, types.Int16, types.Int32:
		g.Printf("const %s %s = %s;\n", objcType, cName, o.Val())

	case types.Int64, types.UntypedInt:
		i, exact := constant.Int64Val(o.Val())
		if !exact {
			g.errorf("const value %s for %s cannot be represented as %s", o.Val(), o.Name(), objcType)
			return
		}
		if i == math.MinInt64 {
			// -9223372036854775808LL does not work because 922337203685477508 is
			// larger than max int64.
			g.Printf("const int64_t %s = %dLL-1;\n", cName, i+1)
		} else {
			g.Printf("const int64_t %s = %dLL;\n", cName, i)
		}

	case types.Float32, types.Float64, types.UntypedFloat:
		f, _ := constant.Float64Val(o.Val())
		if math.IsInf(f, 0) || math.Abs(f) > math.MaxFloat64 {
			g.errorf("const value %s for %s cannot be represented as double", o.Val(), o.Name())
			return
		}
		g.Printf("const %s %s = %g;\n", objcType, cName, f)

	default:
		g.errorf("unsupported const type %s for %s", b, o.Name())
	}
}

type funcSummary struct {
	name              string
	ret               string
	sig               *types.Signature
	params, retParams []paramInfo
}

type paramInfo struct {
	typ  types.Type
	name string
}

func (g *objcGen) funcSummary(obj *types.Func) *funcSummary {
	sig := obj.Type().(*types.Signature)
	s := &funcSummary{name: obj.Name(), sig: sig}

	params := sig.Params()
	for i := 0; i < params.Len(); i++ {
		p := params.At(i)
		v := paramInfo{
			typ:  p.Type(),
			name: paramName(params, i),
		}
		s.params = append(s.params, v)
	}

	res := sig.Results()
	switch res.Len() {
	case 0:
		s.ret = "void"
	case 1:
		p := res.At(0)
		if isErrorType(p.Type()) {
			s.retParams = append(s.retParams, paramInfo{
				typ:  p.Type(),
				name: "error",
			})
			s.ret = "BOOL"
		} else {
			name := p.Name()
			if name == "" || paramRE.MatchString(name) {
				name = "ret0_"
			}
			typ := p.Type()
			s.retParams = append(s.retParams, paramInfo{typ: typ, name: name})
			s.ret = g.objcType(typ)
		}
	case 2:
		name := res.At(0).Name()
		if name == "" || paramRE.MatchString(name) {
			name = "ret0_"
		}
		s.retParams = append(s.retParams, paramInfo{
			typ:  res.At(0).Type(),
			name: name,
		})

		if !isErrorType(res.At(1).Type()) {
			g.errorf("second result value must be of type error: %s", obj)
			return nil
		}
		s.retParams = append(s.retParams, paramInfo{
			typ:  res.At(1).Type(),
			name: "error", // TODO(hyangah): name collision check.
		})
		s.ret = "BOOL"
	default:
		// TODO(hyangah): relax the constraint on multiple return params.
		g.errorf("too many result values: %s", obj)
		return nil
	}

	return s
}

func (s *funcSummary) asFunc(g *objcGen) string {
	var params []string
	for _, p := range s.params {
		params = append(params, g.objcType(p.typ)+" "+p.name)
	}
	if !s.returnsVal() {
		for _, p := range s.retParams {
			params = append(params, g.objcType(p.typ)+"* "+p.name)
		}
	}
	return fmt.Sprintf("%s %s%s(%s)", s.ret, g.namePrefix, s.name, strings.Join(params, ", "))
}

func (s *funcSummary) asMethod(g *objcGen) string {
	var params []string
	for i, p := range s.params {
		var key string
		if i != 0 {
			key = p.name
		}
		params = append(params, fmt.Sprintf("%s:(%s)%s", key, g.objcType(p.typ), p.name))
	}
	if !s.returnsVal() {
		for _, p := range s.retParams {
			var key string
			if len(params) > 0 {
				key = p.name
			}
			params = append(params, fmt.Sprintf("%s:(%s)%s", key, g.objcType(p.typ)+"*", p.name))
		}
	}
	return fmt.Sprintf("(%s)%s%s", s.ret, objcNameReplacer(lowerFirst(s.name)), strings.Join(params, " "))
}

func (s *funcSummary) callMethod(g *objcGen) string {
	var params []string
	for i, p := range s.params {
		var key string
		if i != 0 {
			key = p.name
		}
		params = append(params, fmt.Sprintf("%s:_%s", key, p.name))
	}
	if !s.returnsVal() {
		for _, p := range s.retParams {
			var key string
			if len(params) > 0 {
				key = p.name
			}
			params = append(params, fmt.Sprintf("%s:&%s", key, p.name))
		}
	}
	return fmt.Sprintf("%s%s", objcNameReplacer(lowerFirst(s.name)), strings.Join(params, " "))
}

func (s *funcSummary) returnsVal() bool {
	return len(s.retParams) == 1 && !isErrorType(s.retParams[0].typ)
}

func (g *objcGen) genFuncH(obj *types.Func) {
	if !g.isSigSupported(obj.Type()) {
		g.Printf("// skipped function %s with unsupported parameter or return types\n\n", obj.Name())
		return
	}
	if s := g.funcSummary(obj); s != nil {
		g.Printf("FOUNDATION_EXPORT %s;\n", s.asFunc(g))
	}
}

func (g *objcGen) genFuncM(obj *types.Func) {
	s := g.funcSummary(obj)
	if s == nil {
		return
	}
	g.Printf("%s {\n", s.asFunc(g))
	g.Indent()
	g.genFunc(s, "")
	g.Outdent()
	g.Printf("}\n")
}

func (g *objcGen) genGetter(oName string, f *types.Var) {
	t := f.Type()
	g.Printf("- (%s)%s {\n", g.objcType(t), objcNameReplacer(lowerFirst(f.Name())))
	g.Indent()
	g.Printf("int32_t refnum = go_seq_go_to_refnum(self._ref);\n")
	g.Printf("%s r0 = ", g.cgoType(f.Type()))
	g.Printf("proxy%s_%s_%s_Get(refnum);\n", g.pkgPrefix, oName, f.Name())
	g.genRead("_r0", "r0", f.Type(), modeRetained)
	g.Printf("return _r0;\n")
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *objcGen) genSetter(oName string, f *types.Var) {
	t := f.Type()

	g.Printf("- (void)set%s:(%s)v {\n", f.Name(), g.objcType(t))
	g.Indent()
	g.Printf("int32_t refnum = go_seq_go_to_refnum(self._ref);\n")
	g.genWrite("v", f.Type(), modeRetained)
	g.Printf("proxy%s_%s_%s_Set(refnum, _v);\n", g.pkgPrefix, oName, f.Name())
	g.genRelease("v", f.Type(), modeRetained)
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *objcGen) genWrite(varName string, t types.Type, mode varMode) {
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.String:
			g.Printf("nstring _%s = go_seq_from_objc_string(%s);\n", varName, varName)
		default:
			g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
		}
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				g.Printf("nbyteslice _%s = go_seq_from_objc_bytearray(%s, %d);\n", varName, varName, toCFlag(mode == modeRetained))
			default:
				g.errorf("unsupported type: %s", t)
			}
		default:
			g.errorf("unsupported type: %s", t)
		}
	case *types.Named:
		switch u := t.Underlying().(type) {
		case *types.Interface:
			g.genRefWrite(varName, t)
		default:
			g.errorf("unsupported named type: %s / %T", u, u)
		}
	case *types.Pointer:
		g.genRefWrite(varName, t)
	default:
		g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName)
	}
}

func (g *objcGen) genRefWrite(varName string, t types.Type) {
	g.Printf("int32_t _%s;\n", varName)
	g.Printf("if ([(id<NSObject>)(%s) isKindOfClass:[%s class]]) {\n", varName, g.refTypeBase(t))
	g.Indent()
	g.Printf("id<goSeqRefInterface> %[1]s_proxy = (id<goSeqRefInterface>)(%[1]s);\n", varName)
	g.Printf("_%s = go_seq_go_to_refnum(%s_proxy._ref);\n", varName, varName)
	g.Outdent()
	g.Printf("} else {\n")
	g.Indent()
	g.Printf("_%s = go_seq_to_refnum(%s);\n", varName, varName)
	g.Outdent()
	g.Printf("}\n")
}

func (g *objcGen) genRefRead(toName, fromName string, t types.Type) {
	ptype := g.refTypeBase(t)
	g.Printf("%s* %s = nil;\n", ptype, toName)
	g.Printf("GoSeqRef* %s_ref = go_seq_from_refnum(%s);\n", toName, fromName)
	g.Printf("if (%s_ref != NULL) {\n", toName)
	g.Printf("	%s = %s_ref.obj;\n", toName, toName)
	g.Printf("	if (%s == nil) {\n", toName)
	g.Printf("		%s = [[%s alloc] initWithRef:%s_ref];\n", toName, ptype, toName)
	g.Printf("	}\n")
	g.Printf("}\n")
}

func (g *objcGen) genRead(toName, fromName string, t types.Type, mode varMode) {
	switch t := t.(type) {
	case *types.Basic:
		switch t.Kind() {
		case types.String:
			g.Printf("NSString *%s = go_seq_to_objc_string(%s);\n", toName, fromName)
		case types.Bool:
			g.Printf("BOOL %s = %s ? YES : NO;\n", toName, fromName)
		default:
			g.Printf("%s %s = (%s)%s;\n", g.objcType(t), toName, g.objcType(t), fromName)
		}
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				g.Printf("NSData *%s = go_seq_to_objc_bytearray(%s, %d);\n", toName, fromName, toCFlag(mode == modeRetained))
			default:
				g.errorf("unsupported type: %s", t)
			}
		default:
			g.errorf("unsupported type: %s", t)
		}
	case *types.Pointer:
		switch t := t.Elem().(type) {
		case *types.Named:
			g.genRefRead(toName, fromName, types.NewPointer(t))
		default:
			g.errorf("unsupported type %s", t)
		}
	case *types.Named:
		switch t.Underlying().(type) {
		case *types.Interface, *types.Pointer:
			g.genRefRead(toName, fromName, t)
		default:
			g.errorf("unsupported, direct named type %s", t)
		}
	default:
		g.Printf("%s %s = (%s)%s;\n", g.objcType(t), toName, g.objcType(t), fromName)
	}
}

func (g *objcGen) genFunc(s *funcSummary, objName string) {
	if objName != "" {
		g.Printf("int32_t refnum = go_seq_go_to_refnum(self._ref);\n")
	}
	for _, p := range s.params {
		g.genWrite(p.name, p.typ, modeTransient)
	}
	resPrefix := ""
	if len(s.retParams) > 0 {
		if len(s.retParams) == 1 {
			g.Printf("%s r0 = ", g.cgoType(s.retParams[0].typ))
		} else {
			resPrefix = "res."
			g.Printf("struct proxy%s_%s_%s_return res = ", g.pkgPrefix, objName, s.name)
		}
	}
	g.Printf("proxy%s_%s_%s(", g.pkgPrefix, objName, s.name)
	if objName != "" {
		g.Printf("refnum")
	}
	for i, p := range s.params {
		if i > 0 || objName != "" {
			g.Printf(", ")
		}
		g.Printf("_%s", p.name)
	}
	g.Printf(");\n")
	for _, p := range s.params {
		g.genRelease(p.name, p.typ, modeTransient)
	}

	for i, r := range s.retParams {
		g.genRead("_"+r.name, fmt.Sprintf("%sr%d", resPrefix, i), r.typ, modeRetained)
	}

	if !s.returnsVal() {
		for _, p := range s.retParams {
			if isErrorType(p.typ) {
				g.Printf("if (_%s != nil && %s != nil) {\n", p.name, p.name)
				g.Indent()
				g.Printf("*%s = _%s;\n", p.name, p.name)
				g.Outdent()
				g.Printf("}\n")
			} else {
				g.Printf("*%s = _%s;\n", p.name, p.name)
			}
		}
	}

	if n := len(s.retParams); n > 0 {
		p := s.retParams[n-1]
		if isErrorType(p.typ) {
			g.Printf("return (_%s == nil);\n", p.name)
		} else {
			g.Printf("return _%s;\n", p.name)
		}
	}
}

func (g *objcGen) genInterfaceInterface(obj *types.TypeName, summary ifaceSummary, isProtocol bool) {
	g.Printf("@interface %[1]s%[2]s : ", g.namePrefix, obj.Name())
	if isErrorType(obj.Type()) {
		g.Printf("NSError")
	} else {
		g.Printf("NSObject")
	}
	if isProtocol {
		g.Printf(" <%[1]s%[2]s>", g.namePrefix, obj.Name())
	}
	g.Printf(" {\n}\n")
	g.Printf("@property(strong, readonly) id _ref;\n")
	g.Printf("\n")
	g.Printf("- (instancetype)initWithRef:(id)ref;\n")
	for _, m := range summary.callable {
		if !g.isSigSupported(m.Type()) {
			g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name())
			continue
		}
		s := g.funcSummary(m)
		g.Printf("- %s;\n", s.asMethod(g))
	}
	g.Printf("@end\n")
}

func (g *objcGen) genInterfaceH(obj *types.TypeName, t *types.Interface) {
	summary := makeIfaceSummary(t)
	if !summary.implementable {
		g.genInterfaceInterface(obj, summary, false)
		return
	}
	g.Printf("@protocol %s%s\n", g.namePrefix, obj.Name())
	for _, m := range makeIfaceSummary(t).callable {
		if !g.isSigSupported(m.Type()) {
			g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name())
			continue
		}
		s := g.funcSummary(m)
		g.Printf("- %s;\n", s.asMethod(g))
	}
	g.Printf("@end\n")
}

func (g *objcGen) genInterfaceM(obj *types.TypeName, t *types.Interface) bool {
	summary := makeIfaceSummary(t)

	// @implementation Interface -- similar to what genStructM does.
	g.Printf("@implementation %s%s {\n", g.namePrefix, obj.Name())
	g.Printf("}\n")
	g.Printf("\n")
	g.Printf("- (instancetype)initWithRef:(id)ref {\n")
	g.Indent()
	if isErrorType(obj.Type()) {
		g.Printf("if (self) {\n")
		g.Printf("	__ref = ref;\n")
		g.Printf("	self = [super initWithDomain:@\"go\" code:1 userInfo:@{NSLocalizedDescriptionKey: [self error]}];\n")
		g.Printf("}\n")
	} else {
		g.Printf("self = [super init];\n")
		g.Printf("if (self) { __ref = ref; }\n")
	}
	g.Printf("return self;\n")
	g.Outdent()
	g.Printf("}\n")
	g.Printf("\n")

	for _, m := range summary.callable {
		if !g.isSigSupported(m.Type()) {
			g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name())
			continue
		}
		s := g.funcSummary(m)
		g.Printf("- %s {\n", s.asMethod(g))
		g.Indent()
		g.genFunc(s, obj.Name())
		g.Outdent()
		g.Printf("}\n\n")
	}
	g.Printf("@end\n")
	g.Printf("\n")

	return summary.implementable
}

func (g *objcGen) genInterfaceMethodProxy(obj *types.TypeName, m *types.Func) {
	oName := obj.Name()
	s := g.funcSummary(m)
	g.genInterfaceMethodSignature(m, oName, false)
	g.Indent()
	g.Printf("@autoreleasepool {\n")
	g.Indent()
	g.Printf("%s* o = go_seq_objc_from_refnum(refnum);\n", g.refTypeBase(obj.Type()))
	for _, p := range s.params {
		g.genRead("_"+p.name, p.name, p.typ, modeTransient)
	}

	// call method
	if !s.returnsVal() {
		for _, p := range s.retParams {
			if isErrorType(p.typ) {
				g.Printf("NSError* %s = nil;\n", p.name)
			} else {
				g.Printf("%s %s;\n", g.objcType(p.typ), p.name)
			}
		}
	}

	if isErrorType(obj.Type()) && m.Name() == "Error" {
		// As a special case, ObjC NSErrors are passed to Go pretending to implement the Go error interface.
		// They don't actually have an Error method, so calls to to it needs to be rerouted.
		g.Printf("NSString *returnVal = [o localizedDescription];\n")
	} else {
		if s.ret == "void" {
			g.Printf("[o %s];\n", s.callMethod(g))
		} else {
			g.Printf("%s returnVal = [o %s];\n", s.ret, s.callMethod(g))
		}
	}

	if len(s.retParams) > 0 {
		if s.returnsVal() { // len(s.retParams) == 1 && s.retParams[0] != error
			p := s.retParams[0]
			g.genWrite("returnVal", p.typ, modeRetained)
			g.Printf("return _returnVal;\n")
		} else {
			var rets []string
			for i, p := range s.retParams {
				if isErrorType(p.typ) {
					g.Printf("id<GoUniverseerror> _%s = nil;\n", p.name)
					if i == len(s.retParams)-1 { // last param.
						g.Printf("if (!returnVal) {\n")
					} else {
						g.Printf("if (%s != nil) {\n", p.name)
					}
					g.Indent()
					g.Printf("_%[1]s = %[1]s;\n", p.name)
					g.Outdent()
					g.Printf("}\n")
					g.genWrite("_"+p.name, p.typ, modeRetained)
					rets = append(rets, "__"+p.name)
				} else {
					g.genWrite(p.name, p.typ, modeRetained)
					rets = append(rets, "_"+p.name)
				}
			}
			if len(rets) > 1 {
				g.Printf("cproxy%s_%s_%s_return _sres = {\n", g.pkgPrefix, oName, m.Name())
				g.Printf("  %s\n", strings.Join(rets, ", "))
				g.Printf("};\n")
				g.Printf("return _sres;\n")
			} else {
				g.Printf("return %s;\n", rets[0])
			}
		}
	}
	g.Outdent()
	g.Printf("}\n")
	g.Outdent()
	g.Printf("}\n\n")
}

// genRelease cleans up arguments that weren't copied in genWrite.
func (g *objcGen) genRelease(varName string, t types.Type, mode varMode) {
	switch t := t.(type) {
	case *types.Slice:
		switch e := t.Elem().(type) {
		case *types.Basic:
			switch e.Kind() {
			case types.Uint8: // Byte.
				if mode == modeTransient {
					// If the argument was not mutable, go_seq_from_objc_bytearray created a copy.
					// Free it here.
					g.Printf("if (![%s isKindOfClass:[NSMutableData class]]) {\n", varName)
					g.Printf("  free(_%s.ptr);\n", varName)
					g.Printf("}\n")
				}
			}
		}
	}
}

func (g *objcGen) genStructH(obj *types.TypeName, t *types.Struct) {
	g.Printf("@interface %s%s : NSObject {\n", g.namePrefix, obj.Name())
	g.Printf("}\n")
	g.Printf("@property(strong, readonly) id _ref;\n")
	g.Printf("\n")
	g.Printf("- (id)initWithRef:(id)ref;\n")

	// accessors to exported fields.
	for _, f := range exportedFields(t) {
		if t := f.Type(); !g.isSupported(t) {
			g.Printf("// skipped field %s.%s with unsupported type: %T\n\n", obj.Name(), f.Name(), t)
			continue
		}
		name, typ := f.Name(), g.objcFieldType(f.Type())
		g.Printf("- (%s)%s;\n", typ, objcNameReplacer(lowerFirst(name)))
		g.Printf("- (void)set%s:(%s)v;\n", name, typ)
	}

	// exported methods
	for _, m := range exportedMethodSet(types.NewPointer(obj.Type())) {
		if !g.isSigSupported(m.Type()) {
			g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name())
			continue
		}
		s := g.funcSummary(m)
		g.Printf("- %s;\n", objcNameReplacer(lowerFirst(s.asMethod(g))))
	}
	g.Printf("@end\n")
}

func (g *objcGen) genStructM(obj *types.TypeName, t *types.Struct) {
	fields := exportedFields(t)
	methods := exportedMethodSet(types.NewPointer(obj.Type()))

	g.Printf("\n")
	g.Printf("@implementation %s%s {\n", g.namePrefix, obj.Name())
	g.Printf("}\n\n")
	g.Printf("- (id)initWithRef:(id)ref {\n")
	g.Indent()
	g.Printf("self = [super init];\n")
	g.Printf("if (self) { __ref = ref; }\n")
	g.Printf("return self;\n")
	g.Outdent()
	g.Printf("}\n\n")

	for _, f := range fields {
		if !g.isSupported(f.Type()) {
			g.Printf("// skipped unsupported field %s with type %T\n\n", f.Name(), f)
			continue
		}
		g.genGetter(obj.Name(), f)
		g.genSetter(obj.Name(), f)
	}

	for _, m := range methods {
		if !g.isSigSupported(m.Type()) {
			g.Printf("// skipped method %s.%s with unsupported parameter or return types\n\n", obj.Name(), m.Name())
			continue
		}
		s := g.funcSummary(m)
		g.Printf("- %s {\n", s.asMethod(g))
		g.Indent()
		g.genFunc(s, obj.Name())
		g.Outdent()
		g.Printf("}\n\n")
	}
	g.Printf("@end\n")
}

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

func (g *objcGen) refTypeBase(typ types.Type) string {
	switch typ := typ.(type) {
	case *types.Pointer:
		if _, ok := typ.Elem().(*types.Named); ok {
			return g.objcType(typ.Elem())
		}
	case *types.Named:
		n := typ.Obj()
		if isErrorType(typ) || g.validPkg(n.Pkg()) {
			switch typ.Underlying().(type) {
			case *types.Interface, *types.Struct:
				return g.namePrefixOf(n.Pkg()) + n.Name()
			}
		}
	}

	// fallback to whatever objcType returns. This must not happen.
	return g.objcType(typ)
}

func (g *objcGen) objcFieldType(t types.Type) string {
	if isErrorType(t) {
		return "NSError*"
	}
	return g.objcType(t)
}

func (g *objcGen) objcType(typ types.Type) string {
	if isErrorType(typ) {
		return "NSError*"
	}

	switch typ := typ.(type) {
	case *types.Basic:
		switch typ.Kind() {
		case types.Bool, types.UntypedBool:
			return "BOOL"
		case types.Int:
			return "long"
		case types.Int8:
			return "int8_t"
		case types.Int16:
			return "int16_t"
		case types.Int32, types.UntypedRune: // types.Rune
			return "int32_t"
		case types.Int64, types.UntypedInt:
			return "int64_t"
		case types.Uint8:
			// byte is an alias of uint8, and the alias is lost.
			return "byte"
		case types.Uint16:
			return "uint16_t"
		case types.Uint32:
			return "uint32_t"
		case types.Uint64:
			return "uint64_t"
		case types.Float32:
			return "float"
		case types.Float64, types.UntypedFloat:
			return "double"
		case types.String, types.UntypedString:
			return "NSString*"
		default:
			g.errorf("unsupported type: %s", typ)
			return "TODO"
		}
	case *types.Slice:
		elem := g.objcType(typ.Elem())
		// Special case: NSData seems to be a better option for byte slice.
		if elem == "byte" {
			return "NSData*"
		}
		// TODO(hyangah): support other slice types: NSArray or CFArrayRef.
		// Investigate the performance implication.
		g.errorf("unsupported type: %s", typ)
		return "TODO"
	case *types.Pointer:
		if _, ok := typ.Elem().(*types.Named); ok {
			return g.objcType(typ.Elem()) + "*"
		}
		g.errorf("unsupported pointer to type: %s", typ)
		return "TODO"
	case *types.Named:
		n := typ.Obj()
		if !isErrorType(typ) && !g.validPkg(n.Pkg()) {
			g.errorf("type %s is in package %s, which is not bound", n.Name(), n.Pkg().Name())
			return "TODO"
		}
		switch t := typ.Underlying().(type) {
		case *types.Interface:
			if makeIfaceSummary(t).implementable {
				return "id<" + g.namePrefixOf(n.Pkg()) + n.Name() + ">"
			} else {
				return g.namePrefixOf(n.Pkg()) + n.Name() + "*"
			}
		case *types.Struct:
			return g.namePrefixOf(n.Pkg()) + n.Name()
		}
		g.errorf("unsupported, named type %s", typ)
		return "TODO"
	default:
		g.errorf("unsupported type: %#+v, %s", typ, typ)
		return "TODO"
	}
}

var objcNameReplacer = newNameSanitizer([]string{
	"void", "char", "short", "int", "long", "float", "double", "signed",
	"unsigned", "id", "const", "volatile", "in", "out", "inout", "bycopy",
	"byref", "oneway", "self", "super", "init"})

const (
	objcPreamble = `// Objective-C API for talking to %[1]s Go package.
//   gobind %[2]s %[3]s
//
// File is generated by gobind. Do not edit.

`
)
