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

// This program can be used as go_darwin_arm_exec by the Go tool.
// It executes binaries on an iOS device using the XCode toolchain
// and the ios-deploy program: https://github.com/phonegap/ios-deploy
//
// This script supports an extra flag, -lldb, that pauses execution
// just before the main program begins and allows the user to control
// the remote lldb session. This flag is appended to the end of the
// script's arguments and is not passed through to the underlying
// binary.
//
// This script requires that three environment variables be set:
// 	GOIOS_DEV_ID: The codesigning developer id or certificate identifier
// 	GOIOS_APP_ID: The provisioning app id prefix. Must support wildcard app ids.
// 	GOIOS_TEAM_ID: The team id that owns the app id prefix.
// $GOROOT/misc/ios contains a script, detect.go, that attempts to autodetect these.
package main

import (
	"bytes"
	"errors"
	"flag"
	"fmt"
	"go/build"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"time"
)

const debug = false

var errRetry = errors.New("failed to start test harness (retry attempted)")

var tmpdir string

var (
	devID  string
	appID  string
	teamID string
)

func main() {
	log.SetFlags(0)
	log.SetPrefix("go_darwin_arm_exec: ")
	if debug {
		log.Println(strings.Join(os.Args, " "))
	}
	if len(os.Args) < 2 {
		log.Fatal("usage: go_darwin_arm_exec a.out")
	}

	// e.g. B393DDEB490947F5A463FD074299B6C0AXXXXXXX
	devID = getenv("GOIOS_DEV_ID")

	// e.g. Z8B3JBXXXX.org.golang.sample, Z8B3JBXXXX prefix is available at
	// https://developer.apple.com/membercenter/index.action#accountSummary as Team ID.
	appID = getenv("GOIOS_APP_ID")

	// e.g. Z8B3JBXXXX, available at
	// https://developer.apple.com/membercenter/index.action#accountSummary as Team ID.
	teamID = getenv("GOIOS_TEAM_ID")

	var err error
	tmpdir, err = ioutil.TempDir("", "go_darwin_arm_exec_")
	if err != nil {
		log.Fatal(err)
	}

	// Approximately 1 in a 100 binaries fail to start. If it happens,
	// try again. These failures happen for several reasons beyond
	// our control, but all of them are safe to retry as they happen
	// before lldb encounters the initial getwd breakpoint. As we
	// know the tests haven't started, we are not hiding flaky tests
	// with this retry.
	for i := 0; i < 5; i++ {
		if i > 0 {
			fmt.Fprintln(os.Stderr, "start timeout, trying again")
		}
		err = run(os.Args[1], os.Args[2:])
		if err == nil || err != errRetry {
			break
		}
	}
	if !debug {
		os.RemoveAll(tmpdir)
	}
	if err != nil {
		fmt.Fprintf(os.Stderr, "go_darwin_arm_exec: %v\n", err)
		os.Exit(1)
	}
}

func getenv(envvar string) string {
	s := os.Getenv(envvar)
	if s == "" {
		log.Fatalf("%s not set\nrun $GOROOT/misc/ios/detect.go to attempt to autodetect", s)
	}
	return s
}

func run(bin string, args []string) (err error) {
	appdir := filepath.Join(tmpdir, "gotest.app")
	os.RemoveAll(appdir)
	if err := os.MkdirAll(appdir, 0755); err != nil {
		return err
	}

	if err := cp(filepath.Join(appdir, "gotest"), bin); err != nil {
		return err
	}

	entitlementsPath := filepath.Join(tmpdir, "Entitlements.plist")
	if err := ioutil.WriteFile(entitlementsPath, []byte(entitlementsPlist()), 0744); err != nil {
		return err
	}
	if err := ioutil.WriteFile(filepath.Join(appdir, "Info.plist"), []byte(infoPlist), 0744); err != nil {
		return err
	}
	if err := ioutil.WriteFile(filepath.Join(appdir, "ResourceRules.plist"), []byte(resourceRules), 0744); err != nil {
		return err
	}

	pkgpath, err := copyLocalData(appdir)
	if err != nil {
		return err
	}

	cmd := exec.Command(
		"codesign",
		"-f",
		"-s", devID,
		"--entitlements", entitlementsPath,
		appdir,
	)
	if debug {
		log.Println(strings.Join(cmd.Args, " "))
	}
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("codesign: %v", err)
	}

	oldwd, err := os.Getwd()
	if err != nil {
		return err
	}
	if err := os.Chdir(filepath.Join(appdir, "..")); err != nil {
		return err
	}
	defer os.Chdir(oldwd)

	defer func() {
		if r := recover(); r != nil {
			if w, ok := r.(waitPanic); ok {
				err = w.err
				return
			}
			panic(r)
		}
	}()

	defer exec.Command("killall", "ios-deploy").Run() // cleanup
	exec.Command("killall", "ios-deploy").Run()

	var opts options
	opts, args = parseArgs(args)

	// ios-deploy invokes lldb to give us a shell session with the app.
	s, err := newSession(appdir, args, opts)
	if err != nil {
		return err
	}
	defer func() {
		b := s.out.Bytes()
		if err == nil && !debug {
			i := bytes.Index(b, []byte("(lldb) process continue"))
			if i > 0 {
				b = b[i:]
			}
		}
		os.Stdout.Write(b)
	}()

	// Script LLDB. Oh dear.
	s.do(`process handle SIGHUP  --stop false --pass true --notify false`)
	s.do(`process handle SIGPIPE --stop false --pass true --notify false`)
	s.do(`process handle SIGUSR1 --stop false --pass true --notify false`)
	s.do(`process handle SIGSEGV --stop false --pass true --notify false`) // does not work
	s.do(`process handle SIGBUS  --stop false --pass true --notify false`) // does not work

	if opts.lldb {
		_, err := io.Copy(s.in, os.Stdin)
		if err != io.EOF {
			return err
		}
		return nil
	}

	s.do(`breakpoint set -n getwd`) // in runtime/cgo/gcc_darwin_arm.go

	s.doCmd("run", "stop reason = breakpoint", 20*time.Second)

	// Move the current working directory into the faux gopath.
	if pkgpath != "src" {
		s.do(`breakpoint delete 1`)
		s.do(`expr char* $mem = (char*)malloc(512)`)
		s.do(`expr $mem = (char*)getwd($mem, 512)`)
		s.do(`expr $mem = (char*)strcat($mem, "/` + pkgpath + `")`)
		s.do(`call (void)chdir($mem)`)
	}

	startTestsLen := s.out.Len()
	fmt.Fprintln(s.in, `process continue`)

	passed := func(out *buf) bool {
		// Just to make things fun, lldb sometimes translates \n into \r\n.
		return s.out.LastIndex([]byte("\nPASS\n")) > startTestsLen ||
			s.out.LastIndex([]byte("\nPASS\r")) > startTestsLen ||
			s.out.LastIndex([]byte("\n(lldb) PASS\n")) > startTestsLen ||
			s.out.LastIndex([]byte("\n(lldb) PASS\r")) > startTestsLen
	}
	err = s.wait("test completion", passed, opts.timeout)
	if passed(s.out) {
		// The returned lldb error code is usually non-zero.
		// We check for test success by scanning for the final
		// PASS returned by the test harness, assuming the worst
		// in its absence.
		return nil
	}
	return err
}

type lldbSession struct {
	cmd      *exec.Cmd
	in       *os.File
	out      *buf
	timedout chan struct{}
	exited   chan error
}

func newSession(appdir string, args []string, opts options) (*lldbSession, error) {
	lldbr, in, err := os.Pipe()
	if err != nil {
		return nil, err
	}
	s := &lldbSession{
		in:     in,
		out:    new(buf),
		exited: make(chan error),
	}

	s.cmd = exec.Command(
		// lldb tries to be clever with terminals.
		// So we wrap it in script(1) and be clever
		// right back at it.
		"script",
		"-q", "-t", "0",
		"/dev/null",

		"ios-deploy",
		"--debug",
		"-u",
		"-r",
		"-n",
		`--args=`+strings.Join(args, " ")+``,
		"--bundle", appdir,
	)
	if debug {
		log.Println(strings.Join(s.cmd.Args, " "))
	}

	var out io.Writer = s.out
	if opts.lldb {
		out = io.MultiWriter(out, os.Stderr)
	}
	s.cmd.Stdout = out
	s.cmd.Stderr = out // everything of interest is on stderr
	s.cmd.Stdin = lldbr

	if err := s.cmd.Start(); err != nil {
		return nil, fmt.Errorf("ios-deploy failed to start: %v", err)
	}

	// Manage the -test.timeout here, outside of the test. There is a lot
	// of moving parts in an iOS test harness (notably lldb) that can
	// swallow useful stdio or cause its own ruckus.
	if opts.timeout > 1*time.Second {
		s.timedout = make(chan struct{})
		time.AfterFunc(opts.timeout-1*time.Second, func() {
			close(s.timedout)
		})
	}

	go func() {
		s.exited <- s.cmd.Wait()
	}()

	cond := func(out *buf) bool {
		i0 := s.out.LastIndex([]byte("(lldb)"))
		i1 := s.out.LastIndex([]byte("fruitstrap"))
		i2 := s.out.LastIndex([]byte(" connect"))
		return i0 > 0 && i1 > 0 && i2 > 0
	}
	if err := s.wait("lldb start", cond, 5*time.Second); err != nil {
		fmt.Printf("lldb start error: %v\n", err)
		return nil, errRetry
	}
	return s, nil
}

func (s *lldbSession) do(cmd string) { s.doCmd(cmd, "(lldb)", 0) }

func (s *lldbSession) doCmd(cmd string, waitFor string, extraTimeout time.Duration) {
	startLen := s.out.Len()
	fmt.Fprintln(s.in, cmd)
	cond := func(out *buf) bool {
		i := s.out.LastIndex([]byte(waitFor))
		return i > startLen
	}
	if err := s.wait(fmt.Sprintf("running cmd %q", cmd), cond, extraTimeout); err != nil {
		panic(waitPanic{err})
	}
}

func (s *lldbSession) wait(reason string, cond func(out *buf) bool, extraTimeout time.Duration) error {
	doTimeout := 1*time.Second + extraTimeout
	doTimedout := time.After(doTimeout)
	for {
		select {
		case <-s.timedout:
			if p := s.cmd.Process; p != nil {
				p.Kill()
			}
			return fmt.Errorf("test timeout (%s)", reason)
		case <-doTimedout:
			return fmt.Errorf("command timeout (%s for %v)", reason, doTimeout)
		case err := <-s.exited:
			return fmt.Errorf("exited (%s: %v)", reason, err)
		default:
			if cond(s.out) {
				return nil
			}
			time.Sleep(20 * time.Millisecond)
		}
	}
}

type buf struct {
	mu  sync.Mutex
	buf []byte
}

func (w *buf) Write(in []byte) (n int, err error) {
	w.mu.Lock()
	defer w.mu.Unlock()
	w.buf = append(w.buf, in...)
	return len(in), nil
}

func (w *buf) LastIndex(sep []byte) int {
	w.mu.Lock()
	defer w.mu.Unlock()
	return bytes.LastIndex(w.buf, sep)
}

func (w *buf) Bytes() []byte {
	w.mu.Lock()
	defer w.mu.Unlock()

	b := make([]byte, len(w.buf))
	copy(b, w.buf)
	return b
}

func (w *buf) Len() int {
	w.mu.Lock()
	defer w.mu.Unlock()
	return len(w.buf)
}

type waitPanic struct {
	err error
}

type options struct {
	timeout time.Duration
	lldb    bool
}

func parseArgs(binArgs []string) (opts options, remainingArgs []string) {
	var flagArgs []string
	for _, arg := range binArgs {
		if strings.Contains(arg, "-test.timeout") {
			flagArgs = append(flagArgs, arg)
		}
		if strings.Contains(arg, "-lldb") {
			flagArgs = append(flagArgs, arg)
			continue
		}
		remainingArgs = append(remainingArgs, arg)
	}
	f := flag.NewFlagSet("", flag.ContinueOnError)
	f.DurationVar(&opts.timeout, "test.timeout", 0, "")
	f.BoolVar(&opts.lldb, "lldb", false, "")
	f.Parse(flagArgs)
	return opts, remainingArgs

}

func copyLocalDir(dst, src string) error {
	if err := os.Mkdir(dst, 0755); err != nil {
		return err
	}

	d, err := os.Open(src)
	if err != nil {
		return err
	}
	defer d.Close()
	fi, err := d.Readdir(-1)
	if err != nil {
		return err
	}

	for _, f := range fi {
		if f.IsDir() {
			if f.Name() == "testdata" {
				if err := cp(dst, filepath.Join(src, f.Name())); err != nil {
					return err
				}
			}
			continue
		}
		if err := cp(dst, filepath.Join(src, f.Name())); err != nil {
			return err
		}
	}
	return nil
}

func cp(dst, src string) error {
	out, err := exec.Command("cp", "-a", src, dst).CombinedOutput()
	if err != nil {
		os.Stderr.Write(out)
	}
	return err
}

func copyLocalData(dstbase string) (pkgpath string, err error) {
	cwd, err := os.Getwd()
	if err != nil {
		return "", err
	}

	finalPkgpath, underGoRoot, err := subdir()
	if err != nil {
		return "", err
	}
	cwd = strings.TrimSuffix(cwd, finalPkgpath)

	// Copy all immediate files and testdata directories between
	// the package being tested and the source root.
	pkgpath = ""
	for _, element := range strings.Split(finalPkgpath, string(filepath.Separator)) {
		if debug {
			log.Printf("copying %s", pkgpath)
		}
		pkgpath = filepath.Join(pkgpath, element)
		dst := filepath.Join(dstbase, pkgpath)
		src := filepath.Join(cwd, pkgpath)
		if err := copyLocalDir(dst, src); err != nil {
			return "", err
		}
	}

	// Copy timezone file.
	//
	// Typical apps have the zoneinfo.zip in the root of their app bundle,
	// read by the time package as the working directory at initialization.
	// As we move the working directory to the GOROOT pkg directory, we
	// install the zoneinfo.zip file in the pkgpath.
	if underGoRoot {
		err := cp(
			filepath.Join(dstbase, pkgpath),
			filepath.Join(cwd, "lib", "time", "zoneinfo.zip"),
		)
		if err != nil {
			return "", err
		}
	}

	return finalPkgpath, nil
}

// subdir determines the package based on the current working directory,
// and returns the path to the package source relative to $GOROOT (or $GOPATH).
func subdir() (pkgpath string, underGoRoot bool, err error) {
	cwd, err := os.Getwd()
	if err != nil {
		return "", false, err
	}
	if root := runtime.GOROOT(); strings.HasPrefix(cwd, root) {
		subdir, err := filepath.Rel(root, cwd)
		if err != nil {
			return "", false, err
		}
		return subdir, true, nil
	}

	for _, p := range filepath.SplitList(build.Default.GOPATH) {
		if !strings.HasPrefix(cwd, p) {
			continue
		}
		subdir, err := filepath.Rel(p, cwd)
		if err == nil {
			return subdir, false, nil
		}
	}
	return "", false, fmt.Errorf(
		"working directory %q is not in either GOROOT(%q) or GOPATH(%q)",
		cwd,
		runtime.GOROOT(),
		build.Default.GOPATH,
	)
}

const infoPlist = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key><string>golang.gotest</string>
<key>CFBundleSupportedPlatforms</key><array><string>iPhoneOS</string></array>
<key>CFBundleExecutable</key><string>gotest</string>
<key>CFBundleVersion</key><string>1.0</string>
<key>CFBundleIdentifier</key><string>golang.gotest</string>
<key>CFBundleResourceSpecification</key><string>ResourceRules.plist</string>
<key>LSRequiresIPhoneOS</key><true/>
<key>CFBundleDisplayName</key><string>gotest</string>
</dict>
</plist>
`

func entitlementsPlist() string {
	return `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>keychain-access-groups</key>
	<array><string>` + appID + `.golang.gotest</string></array>
	<key>get-task-allow</key>
	<true/>
	<key>application-identifier</key>
	<string>` + appID + `.golang.gotest</string>
	<key>com.apple.developer.team-identifier</key>
	<string>` + teamID + `</string>
</dict>
</plist>
`
}

const resourceRules = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>rules</key>
	<dict>
		<key>.*</key>
		<true/>
		<key>Info.plist</key>
		<dict>
			<key>omit</key>
			<true/>
			<key>weight</key>
			<integer>10</integer>
		</dict>
		<key>ResourceRules.plist</key>
		<dict>
			<key>omit</key>
			<true/>
			<key>weight</key>
			<integer>100</integer>
		</dict>
	</dict>
</dict>
</plist>
`
