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

//go:generate go run gendex.go -o dex.go

package main

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"os"
	"os/exec"
	"regexp"
	"strconv"
	"strings"

	"golang.org/x/mobile/internal/sdkpath"
	"golang.org/x/tools/go/packages"
)

var tmpdir string

var cmdBuild = &command{
	run:   runBuild,
	Name:  "build",
	Usage: "[-target android|" + strings.Join(applePlatforms, "|") + "] [-o output] [-bundleid bundleID] [build flags] [package]",
	Short: "compile android APK and iOS app",
	Long: `
Build compiles and encodes the app named by the import path.

The named package must define a main function.

The -target flag takes either android (the default), or one or more
comma-delimited Apple platforms (` + strings.Join(applePlatforms, ", ") + `).

For -target android, if an AndroidManifest.xml is defined in the
package directory, it is added to the APK output. Otherwise, a default
manifest is generated. By default, this builds a fat APK for all supported
instruction sets (arm, 386, amd64, arm64). A subset of instruction sets can
be selected by specifying target type with the architecture name. E.g.
-target=android/arm,android/386.

For Apple -target platforms, gomobile must be run on an OS X machine with
Xcode installed.

By default, -target ios will generate an XCFramework for both ios
and iossimulator. Multiple Apple targets can be specified, creating a "fat"
XCFramework with each slice. To generate a fat XCFramework that supports
iOS, macOS, and macCatalyst for all supportec architectures (amd64 and arm64),
specify -target ios,macos,maccatalyst. A subset of instruction sets can be
selectged by specifying the platform with an architecture name. E.g.
-target=ios/arm64,maccatalyst/arm64.

If the package directory contains an assets subdirectory, its contents
are copied into the output.

Flag -iosversion sets the minimal version of the iOS SDK to compile against.
The default version is 13.0.

Flag -androidapi sets the Android API version to compile against.
The default and minimum is 16.

The -bundleid flag is required for -target ios and sets the bundle ID to use
with the app.

The -o flag specifies the output file name. If not specified, the
output file name depends on the package built.

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

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

func runBuild(cmd *command) (err error) {
	_, err = runBuildImpl(cmd)
	return
}

// runBuildImpl builds a package for mobiles based on the given commands.
// runBuildImpl returns a built package information and an error if exists.
func runBuildImpl(cmd *command) (*packages.Package, error) {
	cleanup, err := buildEnvInit()
	if err != nil {
		return nil, err
	}
	defer cleanup()

	args := cmd.flag.Args()

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

	var buildPath string
	switch len(args) {
	case 0:
		buildPath = "."
	case 1:
		buildPath = args[0]
	default:
		cmd.usage()
		os.Exit(1)
	}

	// TODO(ydnar): this should work, unless build tags affect loading a single package.
	// Should we try to import packages with different build tags per platform?
	pkgs, err := packages.Load(packagesConfig(targets[0]), buildPath)
	if err != nil {
		return nil, err
	}

	// len(pkgs) can be more than 1 e.g., when the specified path includes `...`.
	if len(pkgs) != 1 {
		cmd.usage()
		os.Exit(1)
	}

	pkg := pkgs[0]

	if pkg.Name != "main" && buildO != "" {
		return nil, fmt.Errorf("cannot set -o when building non-main package")
	}

	var nmpkgs map[string]bool
	switch {
	case isAndroidPlatform(targets[0].platform):
		if pkg.Name != "main" {
			for _, t := range targets {
				if err := goBuild(pkg.PkgPath, androidEnv[t.arch]); err != nil {
					return nil, err
				}
			}
			return pkg, nil
		}
		nmpkgs, err = goAndroidBuild(pkg, targets)
		if err != nil {
			return nil, err
		}
	case isApplePlatform(targets[0].platform):
		if !xcodeAvailable() {
			return nil, fmt.Errorf("-target=%s requires XCode", buildTarget)
		}
		if pkg.Name != "main" {
			for _, t := range targets {
				// Catalyst support requires iOS 13+
				v, _ := strconv.ParseFloat(buildIOSVersion, 64)
				if t.platform == "maccatalyst" && v < 13.0 {
					return nil, errors.New("catalyst requires -iosversion=13 or higher")
				}
				if err := goBuild(pkg.PkgPath, appleEnv[t.String()]); err != nil {
					return nil, err
				}
			}
			return pkg, nil
		}
		if buildBundleID == "" {
			return nil, fmt.Errorf("-target=ios requires -bundleid set")
		}
		nmpkgs, err = goAppleBuild(pkg, buildBundleID, targets)
		if err != nil {
			return nil, err
		}
	}

	if !nmpkgs["golang.org/x/mobile/app"] {
		return nil, fmt.Errorf(`%s does not import "golang.org/x/mobile/app"`, pkg.PkgPath)
	}

	return pkg, nil
}

var nmRE = regexp.MustCompile(`[0-9a-f]{8} t _?(?:.*/vendor/)?(golang.org/x.*/[^.]*)`)

func extractPkgs(nm string, path string) (map[string]bool, error) {
	if buildN {
		return map[string]bool{"golang.org/x/mobile/app": true}, nil
	}
	r, w := io.Pipe()
	cmd := exec.Command(nm, path)
	cmd.Stdout = w
	cmd.Stderr = os.Stderr

	nmpkgs := make(map[string]bool)
	errc := make(chan error, 1)
	go func() {
		s := bufio.NewScanner(r)
		for s.Scan() {
			if res := nmRE.FindStringSubmatch(s.Text()); res != nil {
				nmpkgs[res[1]] = true
			}
		}
		errc <- s.Err()
	}()

	err := cmd.Run()
	w.Close()
	if err != nil {
		return nil, fmt.Errorf("%s %s: %v", nm, path, err)
	}
	if err := <-errc; err != nil {
		return nil, fmt.Errorf("%s %s: %v", nm, path, err)
	}
	return nmpkgs, nil
}

var xout io.Writer = os.Stderr

func printcmd(format string, args ...interface{}) {
	cmd := fmt.Sprintf(format+"\n", args...)
	if tmpdir != "" {
		cmd = strings.Replace(cmd, tmpdir, "$WORK", -1)
	}
	if androidHome, err := sdkpath.AndroidHome(); err == nil {
		cmd = strings.Replace(cmd, androidHome, "$ANDROID_HOME", -1)
	}
	if gomobilepath != "" {
		cmd = strings.Replace(cmd, gomobilepath, "$GOMOBILE", -1)
	}
	if gopath := goEnv("GOPATH"); gopath != "" {
		cmd = strings.Replace(cmd, gopath, "$GOPATH", -1)
	}
	if env := os.Getenv("HOMEPATH"); env != "" {
		cmd = strings.Replace(cmd, env, "$HOMEPATH", -1)
	}
	fmt.Fprint(xout, cmd)
}

// "Build flags", used by multiple commands.
var (
	buildA          bool        // -a
	buildI          bool        // -i
	buildN          bool        // -n
	buildV          bool        // -v
	buildX          bool        // -x
	buildO          string      // -o
	buildGcflags    string      // -gcflags
	buildLdflags    string      // -ldflags
	buildTarget     string      // -target
	buildTrimpath   bool        // -trimpath
	buildWork       bool        // -work
	buildBundleID   string      // -bundleid
	buildIOSVersion string      // -iosversion
	buildAndroidAPI int         // -androidapi
	buildTags       stringsFlag // -tags
)

func addBuildFlags(cmd *command) {
	cmd.flag.StringVar(&buildO, "o", "", "")
	cmd.flag.StringVar(&buildGcflags, "gcflags", "", "")
	cmd.flag.StringVar(&buildLdflags, "ldflags", "", "")
	cmd.flag.StringVar(&buildTarget, "target", "android", "")
	cmd.flag.StringVar(&buildBundleID, "bundleid", "", "")
	cmd.flag.StringVar(&buildIOSVersion, "iosversion", "13.0", "")
	cmd.flag.IntVar(&buildAndroidAPI, "androidapi", minAndroidAPI, "")

	cmd.flag.BoolVar(&buildA, "a", false, "")
	cmd.flag.BoolVar(&buildI, "i", false, "")
	cmd.flag.BoolVar(&buildTrimpath, "trimpath", false, "")
	cmd.flag.Var(&buildTags, "tags", "")
}

func addBuildFlagsNVXWork(cmd *command) {
	cmd.flag.BoolVar(&buildN, "n", false, "")
	cmd.flag.BoolVar(&buildV, "v", false, "")
	cmd.flag.BoolVar(&buildX, "x", false, "")
	cmd.flag.BoolVar(&buildWork, "work", false, "")
}

func init() {
	addBuildFlags(cmdBuild)
	addBuildFlagsNVXWork(cmdBuild)

	addBuildFlags(cmdInstall)
	addBuildFlagsNVXWork(cmdInstall)

	addBuildFlagsNVXWork(cmdInit)

	addBuildFlags(cmdBind)
	addBuildFlagsNVXWork(cmdBind)

	addBuildFlagsNVXWork(cmdClean)
}

func goBuild(src string, env []string, args ...string) error {
	return goCmd("build", []string{src}, env, args...)
}

func goBuildAt(at string, src string, env []string, args ...string) error {
	return goCmdAt(at, "build", []string{src}, env, args...)
}

func goInstall(srcs []string, env []string, args ...string) error {
	return goCmd("install", srcs, env, args...)
}

func goCmd(subcmd string, srcs []string, env []string, args ...string) error {
	return goCmdAt("", subcmd, srcs, env, args...)
}

func goCmdAt(at string, subcmd string, srcs []string, env []string, args ...string) error {
	cmd := exec.Command("go", subcmd)
	tags := buildTags
	if len(tags) > 0 {
		cmd.Args = append(cmd.Args, "-tags", strings.Join(tags, ","))
	}
	if buildV {
		cmd.Args = append(cmd.Args, "-v")
	}
	if subcmd != "install" && buildI {
		cmd.Args = append(cmd.Args, "-i")
	}
	if buildX {
		cmd.Args = append(cmd.Args, "-x")
	}
	if buildGcflags != "" {
		cmd.Args = append(cmd.Args, "-gcflags", buildGcflags)
	}
	if buildLdflags != "" {
		cmd.Args = append(cmd.Args, "-ldflags", buildLdflags)
	}
	if buildTrimpath {
		cmd.Args = append(cmd.Args, "-trimpath")
	}
	if buildWork {
		cmd.Args = append(cmd.Args, "-work")
	}
	cmd.Args = append(cmd.Args, args...)
	cmd.Args = append(cmd.Args, srcs...)

	// Specify GOMODCACHE explicitly. The default cache path is GOPATH[0]/pkg/mod,
	// but the path varies when GOPATH is specified at env, which results in cold cache.
	if gmc, err := goModCachePath(); err == nil {
		env = append([]string{"GOMODCACHE=" + gmc}, env...)
	} else {
		env = append([]string{}, env...)
	}
	cmd.Env = env
	cmd.Dir = at
	return runCmd(cmd)
}

func goModTidyAt(at string, env []string) error {
	cmd := exec.Command("go", "mod", "tidy")
	if buildV {
		cmd.Args = append(cmd.Args, "-v")
	}

	// Specify GOMODCACHE explicitly. The default cache path is GOPATH[0]/pkg/mod,
	// but the path varies when GOPATH is specified at env, which results in cold cache.
	if gmc, err := goModCachePath(); err == nil {
		env = append([]string{"GOMODCACHE=" + gmc}, env...)
	} else {
		env = append([]string{}, env...)
	}
	cmd.Env = env
	cmd.Dir = at
	return runCmd(cmd)
}

// parseBuildTarget parses buildTarget into 1 or more platforms and architectures.
// Returns an error if buildTarget contains invalid input.
// Example valid target strings:
//
//	android
//	android/arm64,android/386,android/amd64
//	ios,iossimulator,maccatalyst
//	macos/amd64
func parseBuildTarget(buildTarget string) ([]targetInfo, error) {
	if buildTarget == "" {
		return nil, fmt.Errorf(`invalid target ""`)
	}

	targets := []targetInfo{}
	targetsAdded := make(map[targetInfo]bool)

	addTarget := func(platform, arch string) {
		t := targetInfo{platform, arch}
		if targetsAdded[t] {
			return
		}
		targets = append(targets, t)
		targetsAdded[t] = true
	}

	addPlatform := func(platform string) {
		for _, arch := range platformArchs(platform) {
			addTarget(platform, arch)
		}
	}

	var isAndroid, isApple bool
	for _, target := range strings.Split(buildTarget, ",") {
		tuple := strings.SplitN(target, "/", 2)
		platform := tuple[0]
		hasArch := len(tuple) == 2

		if isAndroidPlatform(platform) {
			isAndroid = true
		} else if isApplePlatform(platform) {
			isApple = true
		} else {
			return nil, fmt.Errorf("unsupported platform: %q", platform)
		}
		if isAndroid && isApple {
			return nil, fmt.Errorf(`cannot mix android and Apple platforms`)
		}

		if hasArch {
			arch := tuple[1]
			if !isSupportedArch(platform, arch) {
				return nil, fmt.Errorf(`unsupported platform/arch: %q`, target)
			}
			addTarget(platform, arch)
		} else {
			addPlatform(platform)
		}
	}

	// Special case to build iossimulator if -target=ios
	if buildTarget == "ios" {
		addPlatform("iossimulator")
	}

	return targets, nil
}

type targetInfo struct {
	platform string
	arch     string
}

func (t targetInfo) String() string {
	return t.platform + "/" + t.arch
}

func goModCachePath() (string, error) {
	out, err := exec.Command("go", "env", "GOMODCACHE").Output()
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(out)), nil
}
