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

import (
	"flag"
	"fmt"
	"os"
	"path"
	"path/filepath"
	"runtime"

	"v.io/jiri"
	"v.io/jiri/collect"
	"v.io/jiri/profiles"
	"v.io/jiri/profiles/profilesmanager"
	"v.io/jiri/profiles/profilesreader"
	"v.io/jiri/profiles/profilesutil"
	"v.io/jiri/runutil"
	"v.io/x/lib/envvar"
)

const (
	ndkDownloadBaseURL   = "https://dl.google.com/android/ndk"
	platformToolsBaseURL = "http://tools.android.com/download"
)

type versionSpec struct {
	ndkDownloadURL string
	// seq's chain may be already in progress.
	ndkExtract           func(seq runutil.Sequence, src, dst string) runutil.Sequence
	ndkAPILevel          int
	platformToolsVersion map[string]string
	baseVersion          string // Version of the base profile that this requires
}

func ndkArch(goArch string) (string, error) {
	switch goArch {
	case "386":
		return "x86", nil
	case "amd64":
		return "x86_64", nil
	case "arm":
		return "arm", nil
	default:
		return "", fmt.Errorf("NDK unsupported for GOARCH %s", goArch)
	}
}

func tarExtract(seq runutil.Sequence, src, dst string) runutil.Sequence {
	return seq.Run("tar", "-C", dst, "-xjf", src)
}

func selfExtract(seq runutil.Sequence, src, dst string) runutil.Sequence {
	return seq.Chmod(src, profilesutil.DefaultDirPerm).Run(src, "-y", "-o"+dst)
}

func Register(installer, profile string) {
	arch, err := ndkArch(runtime.GOARCH)
	if err != nil {
		fmt.Fprintf(os.Stderr, "WARNING: android profile not supported: %v\n", err)
		return
	}
	m := &Manager{
		profileInstaller: installer,
		profileName:      profile,
		qualifiedName:    profiles.QualifiedProfileName(installer, profile),
		versionInfo: profiles.NewVersionInfo(profile, map[string]interface{}{
			"3": &versionSpec{
				ndkDownloadURL: fmt.Sprintf("%s/android-ndk-r9d-%s-%s.tar.bz2", ndkDownloadBaseURL, runtime.GOOS, arch),
				ndkExtract:     tarExtract,
				ndkAPILevel:    9,
				baseVersion:    "4",
			},
			"4": &versionSpec{
				ndkDownloadURL: fmt.Sprintf("%s/android-ndk-r10e-%s-%s.bin", ndkDownloadBaseURL, runtime.GOOS, arch),
				ndkExtract:     selfExtract,
				ndkAPILevel:    16,
				baseVersion:    "4",
			},
			"5": &versionSpec{
				ndkDownloadURL: fmt.Sprintf("%s/android-ndk-r10e-%s-%s.bin", ndkDownloadBaseURL, runtime.GOOS, arch),
				ndkExtract:     selfExtract,
				ndkAPILevel:    21,
				baseVersion:    "4",
			},
			"7": &versionSpec{
				ndkDownloadURL: fmt.Sprintf("%s/android-ndk-r10e-%s-%s.bin", ndkDownloadBaseURL, runtime.GOOS, arch),
				ndkExtract:     selfExtract,
				ndkAPILevel:    21,
				baseVersion:    "4",
			},
			"8": &versionSpec{
				ndkDownloadURL: fmt.Sprintf("%s/android-ndk-r10e-%s-%s.bin", ndkDownloadBaseURL, runtime.GOOS, arch),
				ndkExtract:     selfExtract,
				ndkAPILevel:    21,
				platformToolsVersion: map[string]string{
					"darwin": "sdk-repo-darwin-platform-tools-2219242",
					"linux":  "sdk-repo-linux-platform-tools-2219198",
				},
				baseVersion: "4",
			},
			"9": &versionSpec{
				ndkDownloadURL: fmt.Sprintf("%s/android-ndk-r10e-%s-%s.bin", ndkDownloadBaseURL, runtime.GOOS, arch),
				ndkExtract:     selfExtract,
				ndkAPILevel:    21,
				platformToolsVersion: map[string]string{
					"darwin": "sdk-repo-darwin-platform-tools-2219242",
					"linux":  "sdk-repo-linux-platform-tools-2219198",
				},
				baseVersion: "5",
			},
		}, "9"),
	}
	profilesmanager.Register(m)
}

type Manager struct {
	profileInstaller string
	profileName      string
	qualifiedName    string
	root             jiri.RelPath
	androidRoot      jiri.RelPath
	ndkRoot          jiri.RelPath
	platformRoot     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 android profile provides support for cross-compiling from linux or darwin
to android. It only supports one target 'arm-android' and will assume that
as the default value if one is not supplied. It installs the android NDK
and a go compiler configured to use it.`
}

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

func (m *Manager) AddFlags(flags *flag.FlagSet, action profiles.Action) {
}

func (m *Manager) initForTarget(jirix *jiri.X, action string, root jiri.RelPath, target *profiles.Target) error {
	if !target.IsSet() {
		def := *target
		target.Set("arm-android")
		fmt.Fprintf(jirix.Stdout(), "Default target %v reinterpreted as: %v\n", def, target)
	} else {
		if (target.Arch() != "amd64" && target.Arch() != "arm") || target.OS() != "android" {
			return fmt.Errorf("this profile can only be %v as arm-android or amd64-android and not as %v", action, target)
		}
	}
	if err := m.versionInfo.Lookup(target.Version(), &m.spec); err != nil {
		return err
	}
	m.root = root
	m.androidRoot = root.Join("android")
	archName, err := ndkArch(target.Arch())
	if err != nil {
		return err
	}
	m.ndkRoot = m.androidRoot.Join("ndk-toolchain", fmt.Sprintf("%s-%d", archName, m.spec.ndkAPILevel))
	m.platformRoot = m.androidRoot.Join("platform-tools", m.spec.platformToolsVersion[runtime.GOOS])
	return nil
}

func (m *Manager) OSPackages(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) ([]string, error) {
	var pkgs []string
	switch runtime.GOOS {
	case "linux":
		pkgs = []string{"ant", "autoconf", "bzip2", "default-jdk", "gawk", "lib32z1", "lib32stdc++6"}
	case "darwin":
		pkgs = []string{"ant", "autoconf", "gawk"}
	default:
		return nil, fmt.Errorf("unsupported OS: %s", runtime.GOOS)
	}
	return pkgs, nil
}

func (m *Manager) Install(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) error {
	var err error
	var baseEnv []string
	if err = m.initForTarget(jirix, "installed", root, &target); err != nil {
		return err
	}
	if p := pdb.LookupProfileTarget(m.profileInstaller, m.profileName, target); p != nil {
		fmt.Fprintf(jirix.Stdout(), "%v %v is already installed as %v\n", m.profileName, target, p)
		return nil
	}
	if err = m.installAndroidNDK(jirix, target); err != nil {
		return err
	}
	// Note that the ordering is important here.  Installing base depends upon the NDK
	// being installed.  Essentially there is a circular dependency between base and android.
	if baseEnv, err = m.installBase(jirix, pdb, root, target); err != nil {
		return err
	}
	if target, err = m.installAndroidPlatformTools(jirix, target); err != nil {
		return err
	}

	// Merge the target and baseProfile environments.
	env := &envvar.Vars{}
	if target.Arch() == "amd64" {
		ldflags := env.GetTokens("CGO_LDFLAGS", " ")
		ldflags = append(ldflags, m.ndkRoot.Join("x86_64-linux-android", "lib64", "libstdc++.a").Symbolic())
		env.SetTokens("CGO_LDFLAGS", ldflags, " ")
	}
	profilesreader.MergeEnv(profilesreader.ProfileMergePolicies(), env, target.Env.Vars, baseEnv)
	target.Env.Vars = env.ToSlice()
	target.InstallationDir = string(m.androidRoot)
	pdb.InstallProfile(m.profileInstaller, m.profileName, string(m.androidRoot))
	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 {
	pdb.RemoveProfileTarget(m.profileInstaller, m.profileName, target)
	return nil
}

func (m *Manager) installBase(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) ([]string, error) {
	// It turns out that you can't install base for *-android without setting
	// at least one of these variables.
	env := fmt.Sprintf("ANDROID_NDK_DIR=%s,GOARM=7", m.ndkRoot.Symbolic())
	// target.String() only preserves the arch, opsys and version fields.
	// So this is a good way to copy the arch/opsys and we just have to set
	// the version.
	baseTarget, err := profiles.NewTarget(target.String(), env)
	baseTarget.SetVersion(m.spec.baseVersion)
	if err != nil {
		return nil, err
	}
	if err := profilesmanager.EnsureProfileTargetIsInstalled(jirix, pdb, m.profileInstaller, "base", root, baseTarget); err != nil {
		return nil, err
	}
	return pdb.EnvFromProfile(m.profileInstaller, "base", baseTarget), nil
}

// installAndroidNDK installs the android NDK toolchain.
func (m *Manager) installAndroidNDK(jirix *jiri.X, target profiles.Target) (e error) {
	// Download Android NDK.
	installNdkFn := 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)
		extractDir, err := s.TempDir(tmpDir, "extract")
		if err != nil {
			return err
		}
		local := filepath.Join(tmpDir, path.Base(m.spec.ndkDownloadURL))
		s.Run("curl", "-Lo", local, m.spec.ndkDownloadURL)
		files, err := m.spec.ndkExtract(s, local, extractDir).ReadDir(extractDir)
		if err != nil {
			return err
		}
		if len(files) != 1 {
			return fmt.Errorf("expected one directory under %s, got: %v", extractDir, files)
		}
		ndkBin := filepath.Join(extractDir, files[0].Name(), "build", "tools", "make-standalone-toolchain.sh")
		archOption, err := ndkArch(target.Arch())
		if err != nil {
			return err
		}
		ndkArgs := []string{ndkBin, fmt.Sprintf("--platform=android-%d", m.spec.ndkAPILevel), fmt.Sprintf("--arch=%s", archOption), "--install-dir=" + m.ndkRoot.Abs(jirix)}
		return s.Last("bash", ndkArgs...)
	}
	return profilesutil.AtomicAction(jirix, installNdkFn, m.ndkRoot.Abs(jirix), "Download Android NDK")
}

// installAndroidPlatformTools installs the android platform tools.
func (m *Manager) installAndroidPlatformTools(jirix *jiri.X, target profiles.Target) (profiles.Target, error) {
	suffix := m.spec.platformToolsVersion[runtime.GOOS]
	if suffix == "" {
		return target, nil
	}

	tmpDir, err := jirix.NewSeq().TempDir("", "")
	if err != nil {
		return target, err
	}
	defer jirix.NewSeq().RemoveAll(tmpDir)

	outDir := m.platformRoot.Abs(jirix)
	target.Env.Set("PATH=" + m.platformRoot.Symbolic())
	fn := func() error {
		androidPlatformToolsZipFile := filepath.Join(tmpDir, "platform-tools.zip")
		return jirix.NewSeq().
			Call(func() error {
				url := platformToolsBaseURL + "/" + suffix + ".zip"
				return profilesutil.Fetch(jirix, androidPlatformToolsZipFile, url)
			}, "fetch android platform tools").
			Call(func() error {
				return profilesutil.Unzip(jirix, androidPlatformToolsZipFile, tmpDir)
			}, "unzip android platform tools").
			MkdirAll(filepath.Dir(outDir), profilesutil.DefaultDirPerm).
			Rename(filepath.Join(tmpDir, "platform-tools"), outDir).
			Done()
	}
	return target, profilesutil.AtomicAction(jirix, fn, outDir, "Install Android Platform Tools")
}
