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

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

var (
	lang          = flag.String("lang", "java", "target language for bindings, either java, go, or objc (experimental).")
	outdir        = flag.String("outdir", "", "result will be written to the directory instead of stdout.")
	javaPkg       = flag.String("javapkg", "", "custom Java package path prefix. Valid only with -lang=java.")
	prefix        = flag.String("prefix", "", "custom Objective-C name prefix. Valid only with -lang=objc.")
	bootclasspath = flag.String("bootclasspath", "", "Java bootstrap classpath.")
	classpath     = flag.String("classpath", "", "Java classpath.")
)

var usage = `The Gobind tool generates Java language bindings for Go.

For usage details, see doc.go.`

func main() {
	flag.Parse()

	if *lang != "java" && *javaPkg != "" {
		log.Fatalf("Invalid option -javapkg for gobind -lang=%s", *lang)
	} else if *lang != "objc" && *prefix != "" {
		log.Fatalf("Invalid option -prefix for gobind -lang=%s", *lang)
	}

	oldCtx := build.Default
	ctx := &build.Default
	var allPkg []*build.Package
	for _, path := range flag.Args() {
		pkg, err := ctx.Import(path, ".", build.ImportComment)
		if err != nil {
			log.Fatalf("package %q: %v", path, err)
		}
		allPkg = append(allPkg, pkg)
	}
	var classes []*java.Class
	refs, err := importers.AnalyzePackages(allPkg, "Java/")
	if err != nil {
		log.Fatal(err)
	}
	if len(refs.Refs) > 0 {
		imp := &java.Importer{
			Bootclasspath: *bootclasspath,
			Classpath:     *classpath,
			JavaPkg:       *javaPkg,
		}
		classes, err = imp.Import(refs)
		if err != nil {
			log.Fatal(err)
		}
		if len(classes) > 0 {
			tmpGopath, err := ioutil.TempDir(os.TempDir(), "gobind-")
			if err != nil {
				log.Fatal(err)
			}
			defer os.RemoveAll(tmpGopath)
			if err := genJavaPackages(ctx, tmpGopath, classes, refs.Embedders); err != nil {
				log.Fatal(err)
			}
			gopath := ctx.GOPATH
			if gopath != "" {
				gopath = string(filepath.ListSeparator)
			}
			ctx.GOPATH = gopath + tmpGopath
		}
	}

	// Make sure the export data for any imported packages are up to date.
	cmd := exec.Command("go", "install")
	cmd.Args = append(cmd.Args, flag.Args()...)
	cmd.Env = append(os.Environ(), "GOPATH="+ctx.GOPATH)
	if err := cmd.Run(); err != nil {
		// Only report I/O errors. Errors from go install is expected for as-yet
		// undefined Java wrappers.
		if _, ok := err.(*exec.ExitError); !ok {
			fmt.Fprintf(os.Stderr, "%s failed: %v", strings.Join(cmd.Args, " "), err)
			os.Exit(1)
		}
	}

	typePkgs := make([]*types.Package, len(allPkg))
	fset := token.NewFileSet()
	conf := &types.Config{
		Importer: importer.Default(),
	}
	conf.Error = func(err error) {
		// Ignore errors. They're probably caused by as-yet undefined
		// Java wrappers.
	}
	for i, pkg := range allPkg {
		var files []*ast.File
		for _, name := range pkg.GoFiles {
			f, err := parser.ParseFile(fset, filepath.Join(pkg.Dir, name), nil, 0)
			if err != nil {
				log.Fatalf("Failed to parse Go file %s: %v", name, err)
			}
			files = append(files, f)
		}
		tpkg, _ := conf.Check(pkg.Name, fset, files, nil)
		typePkgs[i] = tpkg
	}
	build.Default = oldCtx
	for _, pkg := range typePkgs {
		genPkg(pkg, typePkgs, classes)
	}
	// Generate the error package and support files
	genPkg(nil, typePkgs, classes)
	os.Exit(exitStatus)
}

var exitStatus = 0

func errorf(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format, args...)
	fmt.Fprintln(os.Stderr)
	exitStatus = 1
}
