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

import (
	"bytes"
	"errors"
	"fmt"
	"go/ast"
	"go/build"
	"go/importer"
	"go/token"
	"go/types"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"

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

// ctx, pkg, tmpdir in build.go

var cmdBind = &command{
	run:   runBind,
	Name:  "bind",
	Usage: "[-target android|ios] [-bootclasspath <path>] [-classpath <path>] [-o output] [build flags] [package]",
	Short: "build a library for Android and iOS",
	Long: `
Bind generates language bindings for the package named by the import
path, and compiles a library for the named target system.

The -target flag takes a target system name, either android (the
default) or ios.

For -target android, the bind command produces an AAR (Android ARchive)
file that archives the precompiled Java API stub classes, the compiled
shared libraries, and all asset files in the /assets subdirectory under
the package directory. The output is named '<package_name>.aar' by
default. This AAR file is commonly used for binary distribution of an
Android library project and most Android IDEs support AAR import. For
example, in Android Studio (1.2+), an AAR file can be imported using
the module import wizard (File > New > New Module > Import .JAR or
.AAR package), and setting it as a new dependency
(File > Project Structure > Dependencies).  This requires 'javac'
(version 1.7+) and Android SDK (API level 15 or newer) to build the
library for Android. The environment variable ANDROID_HOME must be set
to the path to Android SDK. The generated Java class is in the java
package 'go.<package_name>' unless -javapkg flag is specified.

By default, -target=android builds shared libraries for all supported
instruction sets (arm, arm64, 386, amd64). A subset of instruction sets
can be selected by specifying target type with the architecture name. E.g.,
-target=android/arm,android/386.

For -target ios, gomobile must be run on an OS X machine with Xcode
installed. Support is not complete. The generated Objective-C types
are prefixed with 'Go' unless the -prefix flag is provided.

For -target android, the -bootclasspath and -classpath flags are used to
control the bootstrap classpath and the classpath for Go wrappers to Java
classes.

The -v flag provides verbose output, including the list of packages built.

The build flags -a, -n, -x, -gcflags, -ldflags, -tags, and -work
are shared with the build command. For documentation, see 'go help build'.
`,
}

func runBind(cmd *command) error {
	cleanup, err := buildEnvInit()
	if err != nil {
		return err
	}
	defer cleanup()

	args := cmd.flag.Args()

	targetOS, targetArchs, err := parseBuildTarget(buildTarget)
	if err != nil {
		return fmt.Errorf(`invalid -target=%q: %v`, buildTarget, err)
	}

	ctx.GOARCH = "arm"
	ctx.GOOS = targetOS

	if ctx.GOOS == "darwin" {
		ctx.BuildTags = append(ctx.BuildTags, "ios")
	}

	if bindJavaPkg != "" && ctx.GOOS != "android" {
		return fmt.Errorf("-javapkg is supported only for android target")
	}
	if bindPrefix != "" && ctx.GOOS != "darwin" {
		return fmt.Errorf("-prefix is supported only for ios target")
	}

	if ctx.GOOS == "android" && ndkRoot == "" {
		return errors.New("no Android NDK path is set. Please run gomobile init with the ndk-bundle installed through the Android SDK manager or with the -ndk flag set.")
	}

	var pkgs []*build.Package
	switch len(args) {
	case 0:
		pkgs = make([]*build.Package, 1)
		pkgs[0], err = ctx.ImportDir(cwd, build.ImportComment)
	default:
		pkgs, err = importPackages(args)
	}
	if err != nil {
		return err
	}

	// check if any of the package is main
	for _, pkg := range pkgs {
		if pkg.Name == "main" {
			return fmt.Errorf("binding 'main' package (%s) is not supported", pkg.ImportComment)
		}
	}

	switch targetOS {
	case "android":
		return goAndroidBind(pkgs, targetArchs)
	case "darwin":
		// TODO: use targetArchs?
		return goIOSBind(pkgs)
	default:
		return fmt.Errorf(`invalid -target=%q`, buildTarget)
	}
}

func importPackages(args []string) ([]*build.Package, error) {
	pkgs := make([]*build.Package, len(args))
	for i, path := range args {
		var err error
		if pkgs[i], err = ctx.Import(path, cwd, build.ImportComment); err != nil {
			return nil, fmt.Errorf("package %q: %v", path, err)
		}
	}
	return pkgs, nil
}

var (
	bindPrefix        string // -prefix
	bindJavaPkg       string // -javapkg
	bindClasspath     string // -classpath
	bindBootClasspath string // -bootclasspath
)

func init() {
	// bind command specific commands.
	cmdBind.flag.StringVar(&bindJavaPkg, "javapkg", "",
		"specifies custom Java package path prefix. Valid only with -target=android.")
	cmdBind.flag.StringVar(&bindPrefix, "prefix", "",
		"custom Objective-C name prefix. Valid only with -target=ios.")
	cmdBind.flag.StringVar(&bindClasspath, "classpath", "", "The classpath for imported Java classes. Valid only with -target=android.")
	cmdBind.flag.StringVar(&bindBootClasspath, "bootclasspath", "", "The bootstrap classpath for imported Java classes. Valid only with -target=android.")
}

type binder struct {
	files []*ast.File
	fset  *token.FileSet
	pkgs  []*types.Package
}

func (b *binder) GenGoSupport(outdir string) error {
	bindPkg, err := ctx.Import("golang.org/x/mobile/bind", "", build.FindOnly)
	if err != nil {
		return err
	}
	return copyFile(filepath.Join(outdir, "seq.go"), filepath.Join(bindPkg.Dir, "seq.go.support"))
}

func (b *binder) GenObjcSupport(outdir string) error {
	objcPkg, err := ctx.Import("golang.org/x/mobile/bind/objc", "", build.FindOnly)
	if err != nil {
		return err
	}
	if err := copyFile(filepath.Join(outdir, "seq_darwin.m"), filepath.Join(objcPkg.Dir, "seq_darwin.m.support")); err != nil {
		return err
	}
	if err := copyFile(filepath.Join(outdir, "seq_darwin.go"), filepath.Join(objcPkg.Dir, "seq_darwin.go.support")); err != nil {
		return err
	}
	if err := copyFile(filepath.Join(outdir, "ref.h"), filepath.Join(objcPkg.Dir, "ref.h")); err != nil {
		return err
	}
	return copyFile(filepath.Join(outdir, "seq.h"), filepath.Join(objcPkg.Dir, "seq.h"))
}

func (b *binder) GenObjc(pkg *types.Package, allPkg []*types.Package, outdir string, wrappers []*objc.Named) (string, error) {
	if pkg == nil {
		bindPrefix = ""
	}
	pkgName := ""
	pkgPath := ""
	if pkg != nil {
		pkgName = pkg.Name()
		pkgPath = pkg.Path()
	} else {
		pkgName = "universe"
	}
	bindOption := "-lang=objc"
	if bindPrefix != "" {
		bindOption += fmt.Sprintf(" -prefix=%q", bindPrefix)
	}

	fileBase := bindPrefix + strings.Title(pkgName)
	mfile := filepath.Join(outdir, fileBase+".m")
	hfile := filepath.Join(outdir, fileBase+".objc.h")
	gohfile := filepath.Join(outdir, pkgName+".h")

	var buf bytes.Buffer
	g := &bind.ObjcGen{
		Generator: &bind.Generator{
			Printer: &bind.Printer{Buf: &buf, IndentEach: []byte("\t")},
			Fset:    b.fset,
			AllPkg:  allPkg,
			Pkg:     pkg,
		},
		Prefix: bindPrefix,
	}
	g.Init(wrappers)

	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind %s -outdir=%s %s", bindOption, outdir, pkgPath)
		}
		if buildN {
			return nil
		}
		buf.Reset()
		if err := g.GenM(); err != nil {
			return err
		}
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(mfile, generate); err != nil {
		return "", err
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		if err := g.GenH(); err != nil {
			return err
		}
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(hfile, generate); err != nil {
		return "", err
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		if err := g.GenGoH(); err != nil {
			return err
		}
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(gohfile, generate); err != nil {
		return "", err
	}

	return fileBase, nil
}

func (b *binder) GenJavaSupport(outdir string) error {
	javaPkg, err := ctx.Import("golang.org/x/mobile/bind/java", "", build.FindOnly)
	if err != nil {
		return err
	}
	if err := copyFile(filepath.Join(outdir, "seq_android.go"), filepath.Join(javaPkg.Dir, "seq_android.go.support")); err != nil {
		return err
	}
	if err := copyFile(filepath.Join(outdir, "seq_android.c"), filepath.Join(javaPkg.Dir, "seq_android.c.support")); err != nil {
		return err
	}
	return copyFile(filepath.Join(outdir, "seq.h"), filepath.Join(javaPkg.Dir, "seq.h"))
}

func bootClasspath() (string, error) {
	if bindBootClasspath != "" {
		return bindBootClasspath, nil
	}
	apiPath, err := androidAPIPath()
	if err != nil {
		return "", err
	}
	return filepath.Join(apiPath, "android.jar"), nil
}

func GenObjcWrappers(pkgs []*build.Package, srcDir, pkgGen string) ([]*objc.Named, error) {
	refs, err := importers.AnalyzePackages(pkgs, "ObjC/")
	if err != nil {
		return nil, err
	}
	types, err := objc.Import(refs)
	if err != nil {
		return nil, err
	}
	var buf bytes.Buffer
	g := &bind.ObjcWrapper{
		Printer: &bind.Printer{
			IndentEach: []byte("\t"),
			Buf:        &buf,
		},
	}
	var genNames []string
	for _, emb := range refs.Embedders {
		genNames = append(genNames, emb.Name)
	}
	g.Init(types, genNames)
	for i, name := range g.Packages() {
		pkgDir := filepath.Join(pkgGen, "src", "ObjC", name)
		if err := os.MkdirAll(pkgDir, 0700); err != nil {
			return nil, err
		}
		pkgFile := filepath.Join(pkgDir, "package.go")
		generate := func(w io.Writer) error {
			if buildN {
				return nil
			}
			buf.Reset()
			g.GenPackage(i)
			_, err := io.Copy(w, &buf)
			return err
		}
		if err := writeFile(pkgFile, generate); err != nil {
			return nil, fmt.Errorf("failed to create the ObjC wrapper package %s: %v", name, err)
		}
	}
	generate := func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		g.GenGo()
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(filepath.Join(srcDir, "interfaces.go"), generate); err != nil {
		return nil, fmt.Errorf("failed to create the ObjC wrapper Go file: %v", err)
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		g.GenInterfaces()
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(filepath.Join(pkgGen, "src", "ObjC", "interfaces.go"), generate); err != nil {
		return nil, fmt.Errorf("failed to create the ObjC wrapper Go file: %v", err)
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		g.GenH()
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(filepath.Join(srcDir, "interfaces.h"), generate); err != nil {
		return nil, fmt.Errorf("failed to create the ObjC wrapper header file: %v", err)
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		g.GenM()
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(filepath.Join(srcDir, "interfaces.m"), generate); err != nil {
		return nil, fmt.Errorf("failed to create the Java classes ObjC file: %v", err)
	}
	return types, nil
}

func GenClasses(pkgs []*build.Package, srcDir, jpkgSrc string) ([]*java.Class, error) {
	refs, err := importers.AnalyzePackages(pkgs, "Java/")
	if err != nil {
		return nil, err
	}
	bClspath, err := bootClasspath()
	if err != nil {
		return nil, err
	}
	imp := &java.Importer{
		Bootclasspath: bClspath,
		Classpath:     bindClasspath,
		JavaPkg:       bindJavaPkg,
	}
	classes, err := imp.Import(refs)
	if err != nil {
		return nil, err
	}
	var buf bytes.Buffer
	g := &bind.ClassGen{
		Printer: &bind.Printer{
			IndentEach: []byte("\t"),
			Buf:        &buf,
		},
	}
	var genNames []string
	for _, emb := range refs.Embedders {
		n := emb.Pkg + "." + emb.Name
		if bindJavaPkg != "" {
			n = bindJavaPkg + "." + n
		}
		genNames = append(genNames, n)
	}
	g.Init(classes, genNames)
	for i, jpkg := range g.Packages() {
		pkgDir := filepath.Join(jpkgSrc, "src", "Java", jpkg)
		if err := os.MkdirAll(pkgDir, 0700); err != nil {
			return nil, err
		}
		pkgFile := filepath.Join(pkgDir, "package.go")
		generate := func(w io.Writer) error {
			if buildN {
				return nil
			}
			buf.Reset()
			g.GenPackage(i)
			_, err := io.Copy(w, &buf)
			return err
		}
		if err := writeFile(pkgFile, generate); err != nil {
			return nil, fmt.Errorf("failed to create the Java wrapper package %s: %v", jpkg, err)
		}
	}
	generate := func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		g.GenGo()
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(filepath.Join(srcDir, "classes.go"), generate); err != nil {
		return nil, fmt.Errorf("failed to create the Java classes Go file: %v", err)
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		g.GenH()
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(filepath.Join(srcDir, "classes.h"), generate); err != nil {
		return nil, fmt.Errorf("failed to create the Java classes header file: %v", err)
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		g.GenC()
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(filepath.Join(srcDir, "classes.c"), generate); err != nil {
		return nil, fmt.Errorf("failed to create the Java classes C file: %v", err)
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		g.GenInterfaces()
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(filepath.Join(jpkgSrc, "src", "Java", "interfaces.go"), generate); err != nil {
		return nil, fmt.Errorf("failed to create the Java classes interfaces file: %v", err)
	}
	return classes, nil
}

func (b *binder) GenJava(pkg *types.Package, allPkg []*types.Package, classes []*java.Class, outdir, androidDir string) error {
	jpkgname := bind.JavaPkgName(bindJavaPkg, pkg)
	javadir := filepath.Join(androidDir, strings.Replace(jpkgname, ".", "/", -1))
	var className string
	pkgName := ""
	pkgPath := ""
	if pkg != nil {
		className = strings.Title(pkg.Name())
		pkgName = pkg.Name()
		pkgPath = pkg.Path()
	} else {
		pkgName = "universe"
		className = "Universe"
	}
	javaFile := filepath.Join(javadir, className+".java")
	cFile := filepath.Join(outdir, "java_"+pkgName+".c")
	hFile := filepath.Join(outdir, pkgName+".h")
	bindOption := "-lang=java"
	if bindJavaPkg != "" {
		bindOption += " -javapkg=" + bindJavaPkg
	}

	var buf bytes.Buffer
	g := &bind.JavaGen{
		JavaPkg: bindJavaPkg,
		Generator: &bind.Generator{
			Printer: &bind.Printer{Buf: &buf, IndentEach: []byte("    ")},
			Fset:    b.fset,
			AllPkg:  allPkg,
			Pkg:     pkg,
		},
	}
	g.Init(classes)

	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind %s -outdir=%s %s", bindOption, javadir, pkgPath)
		}
		if buildN {
			return nil
		}
		buf.Reset()
		if err := g.GenJava(); err != nil {
			return err
		}
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(javaFile, generate); err != nil {
		return err
	}
	for i, name := range g.ClassNames() {
		generate := func(w io.Writer) error {
			if buildN {
				return nil
			}
			buf.Reset()
			if err := g.GenClass(i); err != nil {
				return err
			}
			_, err := io.Copy(w, &buf)
			return err
		}
		classFile := filepath.Join(javadir, name+".java")
		if err := writeFile(classFile, generate); err != nil {
			return err
		}
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		if err := g.GenC(); err != nil {
			return err
		}
		_, err := io.Copy(w, &buf)
		return err
	}
	if err := writeFile(cFile, generate); err != nil {
		return err
	}
	generate = func(w io.Writer) error {
		if buildN {
			return nil
		}
		buf.Reset()
		if err := g.GenH(); err != nil {
			return err
		}
		_, err := io.Copy(w, &buf)
		return err
	}
	return writeFile(hFile, generate)
}

func (b *binder) GenGo(pkg *types.Package, allPkg []*types.Package, outdir string) error {
	pkgName := "go_"
	pkgPath := ""
	if pkg != nil {
		pkgName += pkg.Name()
		pkgPath = pkg.Path()
	}
	goFile := filepath.Join(outdir, pkgName+"main.go")

	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind -lang=go -outdir=%s %s", outdir, pkgPath)
		}
		if buildN {
			return nil
		}
		conf := &bind.GeneratorConfig{
			Writer: w,
			Fset:   b.fset,
			Pkg:    pkg,
			AllPkg: allPkg,
		}
		return bind.GenGo(conf)
	}
	if err := writeFile(goFile, generate); err != nil {
		return err
	}
	return nil
}

func copyFile(dst, src string) error {
	if buildX {
		printcmd("cp %s %s", src, dst)
	}
	return writeFile(dst, func(w io.Writer) error {
		if buildN {
			return nil
		}
		f, err := os.Open(src)
		if err != nil {
			return err
		}
		defer f.Close()

		if _, err := io.Copy(w, f); err != nil {
			return fmt.Errorf("cp %s %s failed: %v", src, dst, err)
		}
		return nil
	})
}

func writeFile(filename string, generate func(io.Writer) error) error {
	if buildV {
		fmt.Fprintf(os.Stderr, "write %s\n", filename)
	}

	err := mkdir(filepath.Dir(filename))
	if err != nil {
		return err
	}

	if buildN {
		return generate(ioutil.Discard)
	}

	f, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer func() {
		if cerr := f.Close(); err == nil {
			err = cerr
		}
	}()

	return generate(f)
}

func loadExportData(pkgs []*build.Package, env []string, args ...string) ([]*types.Package, error) {
	// Compile the package. This will produce good errors if the package
	// doesn't typecheck for some reason, and is a necessary step to
	// building the final output anyway.
	paths := make([]string, len(pkgs))
	for i, p := range pkgs {
		paths[i] = p.ImportPath
	}
	if err := goInstall(paths, env, args...); err != nil {
		return nil, err
	}

	goos, goarch := getenv(env, "GOOS"), getenv(env, "GOARCH")

	// Assemble a fake GOPATH and trick go/importer into using it.
	// Ideally the importer package would let us provide this to
	// it somehow, but this works with what's in Go 1.5 today and
	// gives us access to the gcimporter package without us having
	// to make a copy of it.
	fakegopath := filepath.Join(tmpdir, "fakegopath")
	if err := removeAll(fakegopath); err != nil {
		return nil, err
	}
	if err := mkdir(filepath.Join(fakegopath, "pkg")); err != nil {
		return nil, err
	}
	typePkgs := make([]*types.Package, len(pkgs))
	imp := importer.Default()
	for i, p := range pkgs {
		importPath := p.ImportPath
		src := filepath.Join(pkgdir(env), importPath+".a")
		dst := filepath.Join(fakegopath, "pkg/"+goos+"_"+goarch+"/"+importPath+".a")
		if err := copyFile(dst, src); err != nil {
			return nil, err
		}
		if buildN {
			typePkgs[i] = types.NewPackage(importPath, path.Base(importPath))
			continue
		}
		oldDefault := build.Default
		build.Default = ctx // copy
		build.Default.GOARCH = goarch
		build.Default.GOPATH = fakegopath
		p, err := imp.Import(importPath)
		build.Default = oldDefault
		if err != nil {
			return nil, err
		}
		typePkgs[i] = p
	}
	return typePkgs, nil
}

func newBinder(pkgs []*types.Package) (*binder, error) {
	for _, pkg := range pkgs {
		if pkg.Name() == "main" {
			return nil, fmt.Errorf("package %q (%q): can only bind a library package", pkg.Name(), pkg.Path())
		}
	}
	b := &binder{
		fset: token.NewFileSet(),
		pkgs: pkgs,
	}
	return b, nil
}
