// Copyright 2015 The Vanadium 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 go_profile

import (
	"crypto/sha256"
	"encoding/hex"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"v.io/jiri"
	"v.io/jiri/collect"
	"v.io/jiri/gitutil"
	"v.io/jiri/profiles"
	"v.io/jiri/profiles/profilesmanager"
	"v.io/jiri/profiles/profilesutil"
	"v.io/x/devtools/tooldata"
	"v.io/x/lib/envvar"
)

const (
	go15GitRemote = "https://github.com/golang/go.git"
)

var (
	goSysrootFlag        = ""
	goSysrootDirs        = ""
	defaultGoSysrootDirs = "/lib:/usr/lib:/usr/include"
)

// Supported cross compilation toolchains.
type xspec struct{ arch, os string }
type xbuilder func(*jiri.X, *Manager, jiri.RelPath, profiles.Target, profiles.Action) (bindir string, env []string, e error)

var xcompilers = map[xspec]map[xspec]xbuilder{
	xspec{"amd64", "darwin"}: {
		xspec{"amd64", "linux"}:   darwin_to_linux,
		xspec{"arm", "linux"}:     darwin_to_linux,
		xspec{"arm", "android"}:   to_android,
		xspec{"amd64", "android"}: to_android,
		xspec{"arm", "ios"}:       darwin_to_ios,
		xspec{"arm64", "ios"}:     darwin_to_ios,
		xspec{"386", "ios"}:       darwin_to_ios, // iOS simulator
		xspec{"amd64", "ios"}:     darwin_to_ios, // iOS simulator
	},
	xspec{"amd64", "linux"}: {
		xspec{"amd64", "fnl"}:     to_fnl,
		xspec{"arm", "linux"}:     linux_to_linux,
		xspec{"arm", "android"}:   to_android,
		xspec{"amd64", "android"}: to_android,
	},
}

var osPackages = map[xspec]map[xspec][]string{
	xspec{"amd64", "darwin"}: {},
	xspec{"amd64", "linux"}: {
		xspec{"arm", "linux"}: []string{
			"automake", "bison", "bzip2", "curl", "flex", "g++",
			"gawk", "libexpat1-dev", "gettext", "gperf",
			"libncurses5-dev", "libtool", "subversion", "texinfo",
		},
	},
}

type versionSpec struct {
	gitRevision string
	patchFiles  []string
}

// goRelease enables installation of specific release versions of the Go toolchain.
type goRelease struct {
	file   string
	sha256 string
}

func newGoRelease(version string) *goRelease {
	arch := runtime.GOARCH
	if arch == "arm" {
		arch = "armv6l"
	}
	file := fmt.Sprintf("go%s.%s-%s.tar.gz", version, runtime.GOOS, arch)
	// From: https://golang.org/dl/
	shamap := map[string]string{
		"go1.6.darwin-amd64.tar.gz":  "8b686ace24c0166738fd9f6003503f9d55ce03b7f24c963b043ba7bb56f43000",
		"go1.6.freebsd-386.tar.gz":   "67f0278e0650b303156adbfe012317b9ce75396e3a28cbc0a8210284bb07ab85",
		"go1.6.freebsd-amd64.tar.gz": "3763015cdc7971e10f90fb5bec80d885e9956f836277dcb35a2166ffbd7af9b5",
		"go1.6.linux-386.tar.gz":     "7a240a0f45e559d47ea07319d9faf838225eb9e18174f56a76ccaf9860dbb9b1",
		"go1.6.linux-amd64.tar.gz":   "5470eac05d273c74ff8bac7bef5bad0b5abbd1c4052efbdbc8db45332e836b0b",
		"go1.6.linux-armv6l.tar.gz":  "c6c1859acd3727f23f900bde855b5fd0f74d36b1d10f6dd7beddebfb57513d0b",
		"go1.6.windows-386.zip":      "ac41a46f44d0ea5b83ad7e6a55ee1d58c6a01b7ab7342e243f232510342f16f0",
		"go1.6.windows-amd64.zip":    "1be06afa469666d636a00928755c4bcd6403a01f5761946b2b13b8a664f86bac",
	}
	sha256, ok := shamap[file]
	if !ok {
		return nil
	}
	return &goRelease{file, sha256}
}

func (m *Manager) OSPackages(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) ([]string, error) {
	return osPackages[xspec{runtime.GOARCH, runtime.GOOS}][xspec{target.Arch(), target.OS()}], nil
}

func (g *goRelease) install(jirix *jiri.X, dir string) error {
	s := jirix.NewSeq()
	tmpDir, err := s.TempDir("", "")
	if err != nil {
		return err
	}
	defer jirix.NewSeq().RemoveAll(tmpDir)
	local := filepath.Join(tmpDir, g.file)
	remote := "https://storage.googleapis.com/golang/" + g.file
	if err := profilesutil.Fetch(jirix, local, remote); err != nil {
		return err
	}
	// Verify the checksum of the downloaded file
	csum := sha256.New()
	file, err := os.Open(local)
	if err != nil {
		return err
	}
	defer file.Close()
	if _, err := io.Copy(csum, file); err != nil {
		return fmt.Errorf("failed to checksum %v: %v", file, err)
	}
	file.Close()
	if got, want := hex.EncodeToString(csum.Sum(nil)), g.sha256; got != want {
		return fmt.Errorf("checksum mismatch in download of %q. Got %v, want %v", remote, got, want)
	}
	if strings.HasSuffix(local, ".zip") {
		if err := profilesutil.Unzip(jirix, local, tmpDir); err != nil {
			return err
		}
	} else {
		s = s.Run("tar", "-C", tmpDir, "-xzf", local)
	}
	if err := s.Remove(local).
		MkdirAll(filepath.Dir(dir), profilesutil.DefaultDirPerm).
		Rename(filepath.Join(tmpDir, "go"), dir).
		Done(); err != nil {
		return err
	}
	return nil
}

func Register(installer, profile string) {
	m := &Manager{
		profileInstaller: installer,
		profileName:      profile,
		qualifiedName:    profiles.QualifiedProfileName(installer, profile),
		versionInfo: profiles.NewVersionInfo(profile, map[string]interface{}{
			"1.5": &versionSpec{
				"cc6554f750ccaf63bcdcc478b2a60d71ca76d342", nil},
			"1.5.1": &versionSpec{
				"f2e4c8b5fb3660d793b2c545ef207153db0a34b1", nil},
			// 1.5.1 at a specific git revision, create a new version anytime
			// a new profile is checked in.
			"1.5.1.1:2738c5e0": &versionSpec{
				"492a62e945555bbf94a6f9dd6d430f712738c5e0", nil},
			// 1.5.2 with x86_64 android support
			"1.5.2.1:56093743": &versionSpec{
				"560937434d5f2857bb69e0a6881a38201a197a8d", nil},
			"1.6": &versionSpec{
				"e805bf39458915365924228dc53969ce04e32813", nil},
		}, "1.6"),
	}
	profilesmanager.Register(m)
}

type Manager struct {
	profileInstaller, profileName, qualifiedName string
	root, goRoot                                 jiri.RelPath
	versionInfo                                  *profiles.VersionInfo
	spec                                         versionSpec
}

func (m Manager) Name() string {
	return m.profileName
}

func (m Manager) Installer() string {
	return m.profileInstaller
}

func (m Manager) String() string {
	return fmt.Sprintf("%s[%s]", m.qualifiedName, m.versionInfo.Default())
}

func (m Manager) Info() string {
	return `
The go profile manages installations of the go compiler and in particular configures
them for cross compilation with cgo. A separate build of each cross-compilation
environment is maintained to simplify use of cgo albeit at the cost of some disk space.`
}

func (m Manager) VersionInfo() *profiles.VersionInfo {
	return m.versionInfo
}

func (m *Manager) AddFlags(flags *flag.FlagSet, action profiles.Action) {
	flags.StringVar(&goSysrootFlag, m.profileName+".sysroot-image", "", "sysroot image for cross compiling to the currently specified target")
	flags.StringVar(&goSysrootDirs, m.profileName+".sysroot-image-dirs-to-use", defaultGoSysrootDirs, "a colon separated list of directories to use from the sysroot image")
}

func (m *Manager) initForTarget(jirix *jiri.X, root jiri.RelPath, target *profiles.Target) error {
	m.root = root
	m.goRoot = root.Join("go")
	if err := m.versionInfo.Lookup(target.Version(), &m.spec); err != nil {
		return err
	}
	if jirix.Verbose() {
		fmt.Fprintf(jirix.Stdout(), "Go Profiles: %s\n", m.goRoot)
	}
	return nil
}

func (m *Manager) Install(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) error {
	if err := m.initForTarget(jirix, root, &target); err != nil {
		return err
	}

	jirix.NewSeq().RemoveAll(m.goRoot.Join("go-bootstrap").Abs(jirix))
	cgo := true
	if target.CrossCompiling() {
		// We may need to install an additional cross compilation toolchain
		// for cgo to work.
		if builder := xcompilers[xspec{runtime.GOARCH, runtime.GOOS}][xspec{target.Arch(), target.OS()}]; builder != nil {
			_, vars, err := builder(jirix, m, root, target, profiles.Install)
			if err != nil {
				return err
			}
			target.Env.Vars = vars
		} else if runtime.GOARCH == "amd64" && runtime.GOOS == "linux" && target.Arch() == "386" && target.OS() == "linux" {
			// CGO for 386-linux works on amd64-linux host without cross-compilation.
			cgo = true
		} else {
			// CGO is not supported.
			cgo = false
		}
	}

	// Set GOARCH, GOOS to the values specified in the target, if not set.
	target.Env.Vars = envvar.MergeSlices([]string{
		"GOARCH=" + target.Arch(),
		"GOOS=" + target.OS(),
	}, target.Env.Vars)
	if cgo {
		target.Env.Vars = append(target.Env.Vars, "CGO_ENABLED=1")
	}

	// If a release version of the go toolchain can be used, use that.
	// This allows multiple target architectures to share a single
	// toolchain installation, saving time and space.
	//
	// A release version cannot be used if:
	// (1) Don't know the URL for obtaining it (newGoRelease returns nil), OR
	// (2) Any patches need to be applied to the toolchain code (m.spec.patchFiles), OR
	// (3) Any custom build flags (set via GO_FLAGS environment variable)
	var goInstDir jiri.RelPath
	env := envvar.VarsFromSlice(target.Env.Vars)
	if release := newGoRelease(target.Version()); release != nil &&
		len(m.spec.patchFiles) == 0 &&
		!env.Contains("GO_FLAGS") {
		// Not using a bootstrapped Go, delete any references from env.
		env.Delete("GOROOT_BOOTSTRAP")
		goInstDir = m.goRoot.Join("shared").Join(target.Version())
		fn := func() error { return release.install(jirix, goInstDir.Abs(jirix)) }
		if err := profilesutil.AtomicAction(jirix, fn, goInstDir.Abs(jirix), "Install a release version of the Go toolchain"); err != nil {
			return err
		}
		// CC_FOR_TARGET and CXX_FOR_TARGET might have been set by the
		// cross-compiler setup above. Those variables only take effect
		// when building a Go toolchain.  Instead set CC and CXX.
		if k := "CC_FOR_TARGET"; env.Contains(k) {
			env.Set("CC", abs2symbolic(jirix, env.Get(k)))
			env.Delete(k)
		}
		if k := "CXX_FOR_TARGET"; env.Contains(k) {
			env.Set("CXX", abs2symbolic(jirix, env.Get(k)))
			env.Delete(k)
		}
		if jirix.Verbose() {
			fmt.Fprintf(jirix.Stdout(), "Using Go toolchain in %v for target %v", goInstDir, target)
		}
	} else {
		if jirix.Verbose() {
			fmt.Fprintf(jirix.Stdout(), "Compiling go toolchain at revision %v", m.spec.gitRevision)
		}
		// Compile our own Go toolchain
		targetDir := m.goRoot.Join(target.TargetSpecificDirname())
		goInstDir = targetDir.Join(m.spec.gitRevision)
		goBootstrapDir := targetDir.Join("go-bootstrap")
		if jirix.Verbose() {
			fmt.Fprintf(jirix.Stdout(), "Go Target+Revision %s\n", goInstDir.Abs(jirix))
		}
		if err := m.installGo15Plus(jirix, goBootstrapDir, goInstDir, target.Version(), env); err != nil {
			return err
		}
	}
	env.Set("GOROOT", goInstDir.Symbolic())
	target.Env.Vars = env.ToSlice()
	target.InstallationDir = string(goInstDir)

	pdb.InstallProfile(m.profileInstaller, m.profileName, string(m.goRoot))
	return pdb.AddProfileTarget(m.profileInstaller, m.profileName, target)
}

func (m *Manager) Uninstall(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) error {
	if err := m.initForTarget(jirix, root, &target); err != nil {
		return err
	}

	if target.CrossCompiling() {
		// We may need to install an additional cross compilation toolchain
		// for cgo to work.
		def := profiles.DefaultTarget()
		if builder := xcompilers[xspec{def.Arch(), def.OS()}][xspec{target.Arch(), target.OS()}]; builder != nil {
			if _, _, err := builder(jirix, m, root, target, profiles.Uninstall); err != nil {
				return err
			}
		}
	}
	s := jirix.NewSeq()
	if err := s.RemoveAll(m.goRoot.Join(target.TargetSpecificDirname()).Abs(jirix)).Done(); err != nil {
		return err
	}
	if pdb.RemoveProfileTarget(m.profileInstaller, m.profileName, target) {
		// If there are no more targets then remove the entire go directory,
		// including the bootstrap one.
		return s.RemoveAll(m.goRoot.Abs(jirix)).Done()
	}
	return nil
}

// installGo14 installs Go 1.4 at a given location, using the provided
// environment during compilation.
func installGo14(jirix *jiri.X, go14Dir string, env *envvar.Vars) error {
	installGo14Fn := func() error {
		s := jirix.NewSeq()
		tmpDir, err := s.TempDir("", "")
		if err != nil {
			return err
		}
		defer jirix.NewSeq().RemoveAll(tmpDir)

		name := "go1.4.3.src.tar.gz"
		remote, local := "https://storage.googleapis.com/golang/"+name, filepath.Join(tmpDir, name)
		parentDir := filepath.Dir(go14Dir)
		goSrcDir := filepath.Join(go14Dir, "src")
		makeBin := filepath.Join(goSrcDir, "make.bash")

		if err := s.Run("curl", "-Lo", local, remote).
			Run("tar", "-C", tmpDir, "-xzf", local).
			Remove(local).
			RemoveAll(go14Dir).
			MkdirAll(parentDir, profilesutil.DefaultDirPerm).Done(); err != nil {
			return err
		}
		return s.Rename(filepath.Join(tmpDir, "go"), go14Dir).
			Chdir(goSrcDir).
			Env(env.ToMap()).Last(makeBin, "--no-clean")
	}
	return profilesutil.AtomicAction(jirix, installGo14Fn, go14Dir, "Build and install Go 1.4")
}

// installGo15Plus installs any version of go past 1.5 at the specified git and go
// revision.
func (m *Manager) installGo15Plus(jirix *jiri.X, goBootstrapDir, goInstDir jiri.RelPath, version string, env *envvar.Vars) error {
	// First install bootstrap Go 1.4 for the host.
	if err := installGo14(jirix, goBootstrapDir.Abs(jirix), envvar.VarsFromOS()); err != nil {
		return err
	}
	installGo15Fn := func() error {
		// Clone go1.5 into a tmp directory and then rename it to the
		// final destination.
		s := jirix.NewSeq()
		tmpDir, err := s.TempDir("", "")
		if err != nil {
			return err
		}
		defer jirix.NewSeq().RemoveAll(tmpDir)

		goSrcDir := filepath.Join(goInstDir.Abs(jirix), "src")

		// Git clone the code and get into the right directory.
		if err := s.Pushd(tmpDir).
			Call(func() error { return gitutil.New(jirix.NewSeq()).Clone(go15GitRemote, tmpDir) }, "").
			Call(func() error { return gitutil.New(jirix.NewSeq()).Reset(m.spec.gitRevision) }, "").
			Popd().
			RemoveAll(goInstDir.Abs(jirix)).
			Rename(tmpDir, goInstDir.Abs(jirix)).
			Chmod(goInstDir.Abs(jirix), profilesutil.DefaultDirPerm).
			Done(); err != nil {
			return err
		}

		// Apply patches, if any and build.
		s.Pushd(goSrcDir)
		for _, patchFile := range m.spec.patchFiles {
			s.Run("git", "apply", patchFile)
		}
		makeBin := filepath.Join(goSrcDir, "make.bash")
		env.Set("GOROOT_BOOTSTRAP", goBootstrapDir.Abs(jirix))
		if err := s.Env(env.ToMap()).Last(makeBin); err != nil {
			s.RemoveAll(filepath.Join(goInstDir.Abs(jirix), "bin")).Done()
			return err
		}
		return nil
	}
	if err := profilesutil.AtomicAction(jirix, installGo15Fn, goInstDir.Abs(jirix), "Build and install Go "+version+" @ "+m.spec.gitRevision); err != nil {
		return err
	}
	env.Set("GOROOT_BOOTSTRAP", goBootstrapDir.Symbolic())
	return nil
}

func linux_to_linux(jirix *jiri.X, m *Manager, root jiri.RelPath, target profiles.Target, action profiles.Action) (bindir string, env []string, e error) {
	targetABI := ""
	switch target.Arch() {
	case "arm":
		targetABI = "arm-unknown-linux-gnueabi"
	default:
		return "", nil, fmt.Errorf("Arch %q is not yet supported for crosstools xgcc", target.Arch())
	}
	xgccOutDir := filepath.Join(m.root.Abs(jirix), "profiles", "cout", "xgcc")
	xtoolInstDir := filepath.Join(xgccOutDir, "crosstools-ng-"+targetABI)
	xgccInstDir := filepath.Join(xgccOutDir, targetABI)
	xgccLinkInstDir := filepath.Join(xgccOutDir, "links-"+targetABI)
	if action == profiles.Uninstall {
		s := jirix.NewSeq()
		s.Last("chmod", "-R", "+w", xgccInstDir)
		for _, dir := range []string{xtoolInstDir, xgccInstDir, xgccLinkInstDir} {
			if err := s.RemoveAll(dir).Done(); err != nil {
				return "", nil, err
			}
		}
		return "", nil, nil
	}

	// Build and install crosstool-ng.
	installNgFn := func() error {
		xgccSrcDir := jiri.NewRelPath("third_party", "csrc", "crosstool-ng-1.20.0").Abs(jirix)
		return jirix.NewSeq().
			Pushd(xgccSrcDir).
			Run("autoreconf", "--install", "--force", "--verbose").
			Run("./configure", fmt.Sprintf("--prefix=%v", xtoolInstDir)).
			Run("make", fmt.Sprintf("-j%d", runtime.NumCPU())).
			Run("make", "install").
			Last("make", "distclean")
	}
	if err := profilesutil.AtomicAction(jirix, installNgFn, xtoolInstDir, "Build and install crosstool-ng"); err != nil {
		return "", nil, err
	}

	// Build arm/linux gcc tools.
	installXgccFn := func() error {
		s := jirix.NewSeq()
		tmpDir, err := s.TempDir("", "")
		if err != nil {
			return fmt.Errorf("TempDir() failed: %v", err)
		}
		defer collect.Error(func() error { return jirix.NewSeq().RemoveAll(tmpDir).Done() }, &e)

		bin := filepath.Join(xtoolInstDir, "bin", "ct-ng")
		if err := s.Chdir(tmpDir).Last(bin, targetABI); err != nil {
			return err
		}
		dataPath, err := tooldata.DataDirPath(jirix, "")
		if err != nil {
			return err
		}
		configFile := filepath.Join(dataPath, "crosstool-ng-1.20.0.config")
		config, err := ioutil.ReadFile(configFile)
		if err != nil {
			return fmt.Errorf("ReadFile(%v) failed: %v", configFile, err)
		}
		old, new := "/usr/local/vanadium", filepath.Join(m.root.Abs(jirix), "profiles", "cout")
		newConfig := strings.Replace(string(config), old, new, -1)
		newConfigFile := filepath.Join(tmpDir, ".config")
		if err := s.WriteFile(newConfigFile, []byte(newConfig), profilesutil.DefaultFilePerm).Done(); err != nil {
			return fmt.Errorf("WriteFile(%v) failed: %v", newConfigFile, err)
		}

		dirinfo, err := s.Run(bin, "oldconfig").
			Run(bin, "build").
			Stat(xgccInstDir)
		if err != nil {
			return err
		}
		// crosstool-ng build creates the tool output directory with no write
		// permissions. Change it so that AtomicAction can create the
		// "action completed" file.
		return s.Chmod(xgccInstDir, dirinfo.Mode()|0755).Done()
	}
	if err := profilesutil.AtomicAction(jirix, installXgccFn, xgccInstDir, "Build arm/linux gcc tools"); err != nil {
		return "", nil, err
	}

	linkBinDir := filepath.Join(xgccLinkInstDir, "bin")
	// Create arm/linux gcc symlinks.
	installLinksFn := func() error {
		s := jirix.NewSeq()
		err := s.MkdirAll(linkBinDir, profilesutil.DefaultDirPerm).
			Chdir(xgccLinkInstDir).Done()
		if err != nil {
			return err
		}
		binDir := filepath.Join(xgccInstDir, "bin")
		fileInfoList, err := ioutil.ReadDir(binDir)
		if err != nil {
			return fmt.Errorf("ReadDir(%v) failed: %v", binDir, err)
		}
		for _, fileInfo := range fileInfoList {
			prefix := targetABI + "-"
			if strings.HasPrefix(fileInfo.Name(), prefix) {
				src := filepath.Join(binDir, fileInfo.Name())
				dst := filepath.Join(linkBinDir, strings.TrimPrefix(fileInfo.Name(), prefix))
				if err := s.Symlink(src, dst).Done(); err != nil {
					return err
				}
			}
		}
		return nil
	}
	if err := profilesutil.AtomicAction(jirix, installLinksFn, xgccLinkInstDir, "Create gcc symlinks"); err != nil {
		return "", nil, err
	}
	vars := []string{
		"CC_FOR_TARGET=" + filepath.Join(linkBinDir, "gcc"),
		"CXX_FOR_TARGET=" + filepath.Join(linkBinDir, "g++"),
	}
	return linkBinDir, vars, nil
}

func darwin_to_linux(jirix *jiri.X, m *Manager, root jiri.RelPath, target profiles.Target, action profiles.Action) (bindir string, env []string, e error) {
	if target.Arch() == "arm" {
		return useLLVM(jirix, m, root, target, action)
	}
	return "", nil, fmt.Errorf("cross compilation from darwin to %s linux is not yet supported.", target.Arch())
}

func darwin_to_ios(jirix *jiri.X, m *Manager, root jiri.RelPath, target profiles.Target, action profiles.Action) (bindir string, env []string, e error) {
	if action == profiles.Uninstall {
		return "", nil, nil
	}

	// As of Go 1.6, unable to generate PIC code for 32-bit arm.
	// As of Go 1.5.x, the linker fails for darwin/32-bit
	// As of Go 1.5.1 the linker fails for darwin/32-bit, and is unable to generate PIC code for 32-bit arm
	if target.Arch() == "386" && (target.Version() == "1.5" || strings.HasPrefix(target.Version(), "1.5.")) {
		return "", nil, fmt.Errorf("32-bit iOS simulator is not supported by go yet with c-archive. " +
			"See https://github.com/golang/go/issues/12683")
	}
	if target.Arch() == "arm" {
		return "", nil, fmt.Errorf("32-bit ARM is not supported by go yet as it does not generate PIC code. " +
			"See https://github.com/golang/go/issues/12681")
	}

	vars := []string{
		"CGO_ENABLED=1",
		"CC_FOR_TARGET=" + filepath.Join(jirix.Root, "release", "swift", "clang", "clangwrap.sh"),
		"CXX_FOR_TARGET=" + filepath.Join(jirix.Root, "release", "swift", "clang", "clangwrap++.sh"),
		"GOOS=darwin",
		"GOHOSTARCH=amd64",
		"GOHOSTOS=darwin",
		// We need to explicitly pass the ios build tag to the make.bash script for go so that it won't compile
		// crypto code that's meant for the mac. It'll work on the device because those files have a build tag
		// of !arm64, but the simulator will fail because those specific APIs don't exist on iOS.
		"GO_FLAGS=-tags ios",
	}

	// 32-bit arm is always armv7 in Apple-land
	if target.Arch() == "arm" {
		vars = append(vars, "GOARM=7")
	} else if target.Arch() == "arm64" {
		vars = append(vars, "GOARM=arm64")
	}

	// Add patch for text-relocation errors on arm64
	// Submitted to golang, currently marked for 1.7: https://go-review.googlesource.com/#/c/19206/
	patchPath := filepath.Join(jirix.Root, "release", "go", "src", "v.io", "x", "devtools", "jiri-profile-v23", "go_profile", "macho_linker.patch")
	m.spec.patchFiles = append(m.spec.patchFiles, patchPath)
	return "", vars, nil
}

func to_android(jirix *jiri.X, m *Manager, root jiri.RelPath, target profiles.Target, action profiles.Action) (bindir string, env []string, e error) {
	if action == profiles.Uninstall {
		return "", nil, nil
	}
	ev := envvar.VarsFromSlice(target.CommandLineEnv().Vars)
	jiri.ExpandEnv(jirix, ev)
	ndk := ev.Get("ANDROID_NDK_DIR")
	if len(ndk) == 0 {
		return "", nil, fmt.Errorf("ANDROID_NDK_DIR not specified in the command line environment")
	}
	ndkBin := filepath.Join(ndk, "bin")
	var abi string
	switch target.Arch() {
	case "amd64":
		abi = "x86_64-linux-android"
	case "arm":
		abi = "arm-linux-androideabi"
	default:
		return "", nil, fmt.Errorf("could not locate android abi for target arch %s", target.Arch())
	}
	var (
		cc   = filepath.Join(ndkBin, fmt.Sprintf("%s-gcc", abi))
		cxx  = filepath.Join(ndkBin, fmt.Sprintf("%s-g++", abi))
		vars = []string{
			"CC_FOR_TARGET=" + cc,
			"CXX_FOR_TARGET=" + cxx,
			"CLANG=" + cc,
			"CLANG++=" + cxx,
		}
	)
	return ndkBin, vars, nil
}

func to_fnl(jirix *jiri.X, m *Manager, root jiri.RelPath, target profiles.Target, action profiles.Action) (bindir string, env []string, e error) {
	if action == profiles.Uninstall {
		return "", nil, nil
	}
	fnlRoot := os.Getenv("FNL_JIRI_ROOT")
	if len(fnlRoot) == 0 {
		return "", nil, fmt.Errorf("FNL_JIRI_ROOT not specified in the command line environment")
	}
	muslBin := filepath.Join(fnlRoot, "out/root/tools/x86_64-fuchsia-linux-musl/bin")
	// This cross compiles by building a go compiler with HOST=386 rather than amd64 because
	// the go compiler build process doesn't support building two different versions when
	// host and target are the same.
	// TODO(bprosnitz) Determine whether fnl is linux or a separate os and make the build process cleaner.
	vars := []string{
		"CC_FOR_TARGET=" + filepath.Join(muslBin, "x86_64-fuchsia-linux-musl-gcc"),
		"CXX_FOR_TARGET=" + filepath.Join(muslBin, "x86_64-fuchsia-linux-musl-g++"),
		"GOHOSTARCH=386",
		"GOHOSTOS=linux",
		"GOARCH=amd64",
		"GOOS=linux",
		// Under $JIRI_ROOT, packages for both standard amd64 linux machines and fnl
		// will be placed under "release/go/pkg/linux_amd64" yet be incompatible.
		// This sets a suffix "linux_amd64_musl" for fnl target packages.
		// Note that this isn't a problem for the fnl go cross compiler itself
		// because it is cross compiling from 386 to amd64 and the package
		// directories will not conflict.
		// GO_FLAGS is an environment variable used by go's compiler build scripts
		// to inject flags into the build commands.
		"GO_FLAGS=-installsuffix=musl",
	}
	return "", vars, nil
}

// abs2symbolic is the inverse of jiri.RelPath.Abs
func abs2symbolic(jirix *jiri.X, path string) string {
	if !strings.HasPrefix(path, jirix.Root) {
		return path
	}
	rel, err := filepath.Rel(jirix.Root, path)
	if err != nil {
		return rel
	}
	return jiri.NewRelPath(rel).Symbolic()
}
