// 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{
		JavaPkg: bindJavaPkg,
		Printer: &bind.Printer{
			IndentEach: []byte("\t"),
			Buf:        &buf,
		},
	}
	g.Init(classes, refs.Embedders)
	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
}
