// 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 (
	"fmt"
	"go/ast"
	"go/build"
	"go/importer"
	"go/token"
	"go/types"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"golang.org/x/mobile/bind"
)

// ctx, pkg, tmpdir in build.go

var cmdBind = &command{
	run:   runBind,
	Name:  "bind",
	Usage: "[-target android|ios] [-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 9 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.

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.

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

The build flags -a, -i, -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()

	ctx.GOARCH = "arm"
	switch buildTarget {
	case "android":
		ctx.GOOS = "android"
	case "ios":
		ctx.GOOS = "darwin"
	default:
		return fmt.Errorf(`unknown -target, %q.`, buildTarget)
	}

	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")
	}

	var pkg *build.Package
	switch len(args) {
	case 0:
		pkg, err = ctx.ImportDir(cwd, build.ImportComment)
	case 1:
		pkg, err = ctx.Import(args[0], cwd, build.ImportComment)
	default:
		cmd.usage()
		os.Exit(1)
	}
	if err != nil {
		return err
	}

	switch buildTarget {
	case "android":
		return goAndroidBind(pkg)
	case "ios":
		return goIOSBind(pkg)
	default:
		return fmt.Errorf(`unknown -target, %q.`, buildTarget)
	}
}

var (
	bindPrefix  string // -prefix
	bindJavaPkg string // -javapkg
)

func init() {
	// bind command specific commands.
	cmdBind.flag.StringVar(&bindJavaPkg, "javapkg", "",
		"specifies custom Java package path used instead of the default 'go.<go package name>'. Valid only with -target=android.")
	cmdBind.flag.StringVar(&bindPrefix, "prefix", "",
		"custom Objective-C name prefix used instead of the default 'Go'. Valid only with -lang=ios.")
}

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

func (b *binder) GenObjc(outdir string) error {
	const bindPrefixDefault = "Go"
	if bindPrefix == "" {
		bindPrefix = bindPrefixDefault
	}
	name := strings.Title(b.pkg.Name())
	bindOption := "-lang=objc"
	if bindPrefix != bindPrefixDefault {
		bindOption += " -prefix=" + bindPrefix
	}

	mfile := filepath.Join(outdir, bindPrefix+name+".m")
	hfile := filepath.Join(outdir, bindPrefix+name+".h")

	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind %s -outdir=%s %s", bindOption, outdir, b.pkg.Path())
		}
		return bind.GenObjc(w, b.fset, b.pkg, bindPrefix, false)
	}
	if err := writeFile(mfile, generate); err != nil {
		return err
	}
	generate = func(w io.Writer) error {
		return bind.GenObjc(w, b.fset, b.pkg, bindPrefix, true)
	}
	if err := writeFile(hfile, generate); err != nil {
		return err
	}

	objcPkg, err := ctx.Import("golang.org/x/mobile/bind/objc", "", build.FindOnly)
	if err != nil {
		return err
	}
	return copyFile(filepath.Join(outdir, "seq.h"), filepath.Join(objcPkg.Dir, "seq.h"))
}

func (b *binder) GenJava(outdir string) error {
	className := strings.Title(b.pkg.Name())
	javaFile := filepath.Join(outdir, className+".java")
	bindOption := "-lang=java"
	if bindJavaPkg != "" {
		bindOption += " -javapkg=" + bindJavaPkg
	}

	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind %s -outdir=%s %s", bindOption, outdir, b.pkg.Path())
		}
		return bind.GenJava(w, b.fset, b.pkg, bindJavaPkg)
	}
	if err := writeFile(javaFile, generate); err != nil {
		return err
	}
	return nil
}

func (b *binder) GenGo(outdir string) error {
	pkgName := "go_" + b.pkg.Name()
	outdir = filepath.Join(outdir, pkgName)
	goFile := filepath.Join(outdir, pkgName+"main.go")

	generate := func(w io.Writer) error {
		if buildX {
			printcmd("gobind -lang=go -outdir=%s %s", outdir, b.pkg.Path())
		}
		return bind.GenGo(w, b.fset, b.pkg)
	}
	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(importPath string, 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.
	if err := goInstall(importPath, env, args...); err != nil {
		return nil, err
	}

	// 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
	}
	src := filepath.Join(pkgdir(env), importPath+".a")
	dst := filepath.Join(fakegopath, "pkg/"+getenv(env, "GOOS")+"_"+getenv(env, "GOARCH")+"/"+importPath+".a")
	if err := copyFile(dst, src); err != nil {
		return nil, err
	}
	oldDefault := build.Default
	build.Default = ctx // copy
	build.Default.GOPATH = fakegopath
	p, err := importer.Default().Import(importPath)
	build.Default = oldDefault
	if err != nil {
		return nil, err
	}

	return p, nil
}

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