// Copyright 2015 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

//go:build !ppc64le
// +build !ppc64le

package adb

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"
	"sync"
	"time"

	"github.com/google/syzkaller/pkg/config"
	"github.com/google/syzkaller/pkg/log"
	"github.com/google/syzkaller/pkg/osutil"
	"github.com/google/syzkaller/pkg/report"
	"github.com/google/syzkaller/vm/vmimpl"
)

func init() {
	vmimpl.Register("adb", ctor, false)
}

type Device struct {
	Serial  string `json:"serial"`  // device serial to connect
	Console string `json:"console"` // console device name (e.g. "/dev/pts/0")
}

type Config struct {
	Adb     string            `json:"adb"`     // adb binary name ("adb" by default)
	Devices []json.RawMessage `json:"devices"` // list of adb devices to use

	// Ensure that a device battery level is at 20+% before fuzzing.
	// Sometimes we observe that a device can't charge during heavy fuzzing
	// and eventually powers down (which then requires manual intervention).
	// This option is enabled by default. Turn it off if your devices
	// don't have battery service, or it causes problems otherwise.
	BatteryCheck bool `json:"battery_check"`
	// If this option is set (default), the device is rebooted after each crash.
	// Set it to false to disable reboots.
	TargetReboot  bool   `json:"target_reboot"`
	RepairScript  string `json:"repair_script"`  // script to execute before each startup
	StartupScript string `json:"startup_script"` // script to execute after each startup
}

type Pool struct {
	env *vmimpl.Env
	cfg *Config
}

type instance struct {
	cfg     *Config
	adbBin  string
	device  string
	console string
	closed  chan bool
	debug   bool
}

var (
	androidSerial = "^[0-9A-Za-z]+$"
	ipAddress     = `^(?:localhost|(?:[0-9]{1,3}\.){3}[0-9]{1,3})\:(?:[0-9]{1,5})$` // cuttlefish or remote_device_proxy
	emulatorID    = `^emulator\-\d+$`
)

func loadDevice(data []byte) (*Device, error) {
	devObj := &Device{}
	var devStr string
	err1 := config.LoadData(data, devObj)
	err2 := config.LoadData(data, &devStr)
	if err1 != nil && err2 != nil {
		return nil, fmt.Errorf("failed to parse adb vm config: %w %w", err1, err2)
	}
	if err2 == nil {
		devObj.Serial = devStr
	}
	return devObj, nil
}

func ctor(env *vmimpl.Env) (vmimpl.Pool, error) {
	cfg := &Config{
		Adb:          "adb",
		BatteryCheck: true,
		TargetReboot: true,
	}
	if err := config.LoadData(env.Config, cfg); err != nil {
		return nil, fmt.Errorf("failed to parse adb vm config: %w", err)
	}
	if _, err := exec.LookPath(cfg.Adb); err != nil {
		return nil, err
	}
	if len(cfg.Devices) == 0 {
		return nil, fmt.Errorf("no adb devices specified")
	}
	// Device should be either regular serial number, a valid Cuttlefish ID, or an Android Emulator ID.
	devRe := regexp.MustCompile(fmt.Sprintf("%s|%s|%s", androidSerial, ipAddress, emulatorID))
	for _, dev := range cfg.Devices {
		device, err := loadDevice(dev)
		if err != nil {
			return nil, err
		}
		if !devRe.MatchString(device.Serial) {
			return nil, fmt.Errorf("invalid adb device id '%v'", device.Serial)
		}
	}
	if env.Debug {
		cfg.Devices = cfg.Devices[:1]
	}
	pool := &Pool{
		cfg: cfg,
		env: env,
	}
	return pool, nil
}

func (pool *Pool) Count() int {
	return len(pool.cfg.Devices)
}

func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) {
	device, err := loadDevice(pool.cfg.Devices[index])
	if err != nil {
		return nil, err
	}
	inst := &instance{
		cfg:     pool.cfg,
		adbBin:  pool.cfg.Adb,
		device:  device.Serial,
		console: device.Console,
		closed:  make(chan bool),
		debug:   pool.env.Debug,
	}
	closeInst := inst
	defer func() {
		if closeInst != nil {
			closeInst.Close()
		}
	}()
	if err := inst.repair(); err != nil {
		return nil, err
	}
	if inst.console == "" {
		inst.console = findConsole(inst.adbBin, inst.device)
	}
	log.Logf(0, "associating adb device %v with console %v", inst.device, inst.console)
	if pool.cfg.BatteryCheck {
		if err := inst.checkBatteryLevel(); err != nil {
			return nil, err
		}
	}
	// Remove temp files from previous runs.
	// rm chokes on bad symlinks so we must remove them first
	if _, err := inst.adb("shell", "ls /data/syzkaller*"); err == nil {
		if _, err := inst.adb("shell", "find /data/syzkaller* 2>&1 | grep 'No such file' "+
			"| sed 's/.*\\/data/\\/data/;s/:.*//' | xargs -r unlink"); err != nil {
			return nil, err
		}
		if _, err := inst.adb("shell", "rm -Rf /data/syzkaller*"); err != nil {
			return nil, err
		}
	}
	inst.adb("shell", "echo 0 > /proc/sys/kernel/kptr_restrict")
	closeInst = nil
	return inst, nil
}

var (
	consoleCacheMu sync.Mutex
	consoleToDev   = make(map[string]string)
	devToConsole   = make(map[string]string)
)

func parseAdbOutToInt(out []byte) int {
	val := 0
	for _, c := range out {
		if c >= '0' && c <= '9' {
			val = val*10 + int(c) - '0'
			continue
		}
		if val != 0 {
			break
		}
	}
	return val
}

// findConsole returns console file associated with the dev device (e.g. /dev/ttyUSB0).
// This code was tested with Suzy-Q and Android Serial Cable (ASC). For Suzy-Q see:
// https://chromium.googlesource.com/chromiumos/platform/ec/+/master/docs/case_closed_debugging.md
// The difference between Suzy-Q and ASC is that ASC is a separate cable,
// so it is not possible to match USB bus/port used by adb with the serial console device;
// while Suzy-Q console uses the same USB calbe as adb.
// The overall idea is as follows. We use 'adb shell' to write a unique string onto console,
// then we read from all console devices and see on what console the unique string appears.
func findConsole(adb, dev string) string {
	consoleCacheMu.Lock()
	defer consoleCacheMu.Unlock()
	if con := devToConsole[dev]; con != "" {
		return con
	}
	con, err := findConsoleImpl(adb, dev)
	if err != nil {
		log.Logf(0, "failed to associate adb device %v with console: %v", dev, err)
		log.Logf(0, "falling back to 'adb shell dmesg -w'")
		log.Logf(0, "note: some bugs may be detected as 'lost connection to test machine' with no kernel output")
		con = "adb"
		devToConsole[dev] = con
		return con
	}
	devToConsole[dev] = con
	consoleToDev[con] = dev
	return con
}

func findConsoleImpl(adb, dev string) (string, error) {
	// Attempt to find an exact match, at /dev/ttyUSB.{SERIAL}
	// This is something that can be set up on Linux via 'udev' rules
	exactCon := "/dev/ttyUSB." + dev
	if osutil.IsExist(exactCon) {
		return exactCon, nil
	}

	// Search all consoles, as described in 'findConsole'
	consoles, err := filepath.Glob("/dev/ttyUSB*")
	if err != nil {
		return "", fmt.Errorf("failed to list /dev/ttyUSB devices: %w", err)
	}
	output := make(map[string]*[]byte)
	errors := make(chan error, len(consoles))
	done := make(chan bool)
	for _, con := range consoles {
		if consoleToDev[con] != "" {
			continue
		}
		out := new([]byte)
		output[con] = out
		go func(con string) {
			tty, err := vmimpl.OpenConsole(con)
			if err != nil {
				errors <- err
				return
			}
			defer tty.Close()
			go func() {
				<-done
				tty.Close()
			}()
			*out, _ = io.ReadAll(tty)
			errors <- nil
		}(con)
	}
	if len(output) == 0 {
		return "", fmt.Errorf("no unassociated console devices left")
	}
	time.Sleep(500 * time.Millisecond)
	unique := fmt.Sprintf(">>>%v<<<", dev)
	cmd := osutil.Command(adb, "-s", dev, "shell", "echo", "\"<1>", unique, "\"", ">", "/dev/kmsg")
	if out, err := cmd.CombinedOutput(); err != nil {
		return "", fmt.Errorf("failed to run adb shell: %w\n%s", err, out)
	}
	time.Sleep(500 * time.Millisecond)
	close(done)

	var anyErr error
	for range output {
		err := <-errors
		if anyErr == nil && err != nil {
			anyErr = err
		}
	}

	con := ""
	for con1, out := range output {
		if bytes.Contains(*out, []byte(unique)) {
			if con == "" {
				con = con1
			} else {
				anyErr = fmt.Errorf("device is associated with several consoles: %v and %v", con, con1)
			}
		}
	}

	if con == "" {
		if anyErr != nil {
			return "", anyErr
		}
		return "", fmt.Errorf("no console is associated with this device")
	}
	return con, nil
}

func (inst *instance) Forward(port int) (string, error) {
	var err error
	for i := 0; i < 1000; i++ {
		devicePort := vmimpl.RandomPort()
		_, err = inst.adb("reverse", fmt.Sprintf("tcp:%v", devicePort), fmt.Sprintf("tcp:%v", port))
		if err == nil {
			return fmt.Sprintf("127.0.0.1:%v", devicePort), nil
		}
	}
	return "", err
}

func (inst *instance) adb(args ...string) ([]byte, error) {
	return inst.adbWithTimeout(time.Minute, args...)
}

func (inst *instance) adbWithTimeout(timeout time.Duration, args ...string) ([]byte, error) {
	if inst.debug {
		log.Logf(0, "executing adb %+v", args)
	}
	args = append([]string{"-s", inst.device}, args...)
	out, err := osutil.RunCmd(timeout, "", inst.adbBin, args...)
	if inst.debug {
		log.Logf(0, "adb returned")
	}
	return out, err
}

func (inst *instance) waitForBootCompletion() {
	// ADB connects to a phone and starts syz-fuzzer while the phone is still booting.
	// This enables syzkaller to create a race condition which in certain cases doesn't
	// allow the phone to finalize initialization.
	// To determine whether a system has booted and started all system processes and
	// services we wait for a process named 'com.android.systemui' to start. It's possible
	// that in the future a new devices which doesn't have 'systemui' process will be fuzzed
	// with adb, in this case this code should be modified with a new process name to search for.
	log.Logf(2, "waiting for boot completion")

	sleepTime := 5
	sleepDuration := time.Duration(sleepTime) * time.Second
	maxWaitTime := 60 * 3 // 3 minutes to wait until boot completion
	maxRetries := maxWaitTime / sleepTime
	i := 0
	for ; i < maxRetries; i++ {
		time.Sleep(sleepDuration)

		if out, err := inst.adb("shell", "pgrep systemui | wc -l"); err == nil {
			count := parseAdbOutToInt(out)
			if count != 0 {
				log.Logf(0, "boot completed")
				break
			}
		} else {
			log.Logf(0, "failed to execute command 'pgrep systemui | wc -l', %v", err)
			break
		}
	}
	if i == maxRetries {
		log.Logf(0, "failed to determine boot completion, can't find 'com.android.systemui' process")
	}
}

func (inst *instance) repair() error {
	// Assume that the device is in a bad state initially and reboot it.
	// Ignore errors, maybe we will manage to reboot it anyway.
	if inst.cfg.RepairScript != "" {
		if err := inst.runScript(inst.cfg.RepairScript); err != nil {
			return err
		}
	}
	inst.waitForSSH()
	// History: adb reboot episodically hangs, so we used a more reliable way:
	// using syz-executor to issue reboot syscall. However, this has stopped
	// working, probably due to the introduction of seccomp. Therefore,
	// we revert this to `adb shell reboot` in the meantime, until a more
	// reliable solution can be sought out.
	if inst.cfg.TargetReboot {
		if _, err := inst.adb("shell", "reboot"); err != nil {
			return err
		}
		// Now give it another 5 minutes to boot.
		if !vmimpl.SleepInterruptible(10 * time.Second) {
			return fmt.Errorf("shutdown in progress")
		}
		if err := inst.waitForSSH(); err != nil {
			return err
		}
	}
	// Switch to root for userdebug builds.
	inst.adb("root")
	inst.waitForSSH()
	inst.waitForBootCompletion()

	// Mount debugfs.
	if _, err := inst.adb("shell", "ls /sys/kernel/debug/kcov"); err != nil {
		log.Logf(2, "debugfs was unmounted mounting")
		// This prop only exist on Android 12+
		inst.adb("shell", "setprop persist.dbg.keep_debugfs_mounted 1")
		if _, err := inst.adb("shell", "mount -t debugfs debugfs /sys/kernel/debug "+
			"&& chmod 0755 /sys/kernel/debug"); err != nil {
			return err
		}
	}
	if inst.cfg.StartupScript != "" {
		if err := inst.runScript(inst.cfg.StartupScript); err != nil {
			return err
		}
	}
	return nil
}

func (inst *instance) runScript(script string) error {
	log.Logf(2, "adb: executing %s", script)
	// Execute the contents of the script.
	contents, err := os.ReadFile(script)
	if err != nil {
		return fmt.Errorf("unable to read %s: %w", script, err)
	}
	c := string(contents)
	output, err := osutil.RunCmd(5*time.Minute, "", "sh", "-c", c)
	if err != nil {
		return fmt.Errorf("failed to execute %s: %w", script, err)
	}
	log.Logf(2, "adb: execute %s output\n%s", script, output)
	log.Logf(2, "adb: done executing %s", script)
	return nil
}

func (inst *instance) waitForSSH() error {
	if !vmimpl.SleepInterruptible(time.Second) {
		return fmt.Errorf("shutdown in progress")
	}

	if _, err := inst.adbWithTimeout(10*time.Minute, "wait-for-device"); err != nil {
		return fmt.Errorf("instance is dead and unrepairable: %w", err)
	}

	return nil
}

func (inst *instance) checkBatteryLevel() error {
	const (
		minLevel      = 20
		requiredLevel = 30
	)
	val, err := inst.getBatteryLevel(30)
	if err != nil {
		return err
	}
	if val >= minLevel {
		log.Logf(0, "device %v: battery level %v%%, OK", inst.device, val)
		return nil
	}
	for {
		log.Logf(0, "device %v: battery level %v%%, waiting for %v%%", inst.device, val, requiredLevel)
		if !vmimpl.SleepInterruptible(time.Minute) {
			return nil
		}
		val, err = inst.getBatteryLevel(0)
		if err != nil {
			return err
		}
		if val >= requiredLevel {
			break
		}
	}
	return nil
}

func (inst *instance) getBatteryLevel(numRetry int) (int, error) {
	out, err := inst.adb("shell", "dumpsys battery | grep level:")

	// Allow for retrying for devices that does not boot up so fast.
	for ; numRetry >= 0 && err != nil; numRetry-- {
		if numRetry > 0 {
			// Sleep for 5 seconds before retrying.
			time.Sleep(5 * time.Second)
			out, err = inst.adb("shell", "dumpsys battery | grep level:")
		}
	}
	if err != nil {
		return 0, err
	}
	val := parseAdbOutToInt(out)
	if val == 0 {
		return 0, fmt.Errorf("failed to parse 'dumpsys battery' output: %s", out)
	}
	return val, nil
}

func (inst *instance) Close() {
	close(inst.closed)
}

func (inst *instance) Copy(hostSrc string) (string, error) {
	vmDst := filepath.Join("/data", filepath.Base(hostSrc))
	if _, err := inst.adb("push", hostSrc, vmDst); err != nil {
		return "", err
	}
	return vmDst, nil
}

// Check if the device is cuttlefish on remote vm.
func isRemoteCuttlefish(dev string) (bool, string) {
	if !strings.Contains(dev, ":") {
		return false, ""
	}
	ip := strings.Split(dev, ":")[0]
	if ip == "localhost" || ip == "0.0.0.0" || ip == "127.0.0.1" {
		return false, ip
	}
	return true, ip
}

func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command string) (
	<-chan []byte, <-chan error, error) {
	var tty io.ReadCloser
	var err error

	if ok, ip := isRemoteCuttlefish(inst.device); ok {
		tty, err = vmimpl.OpenRemoteKernelLog(ip, inst.console)
	} else if inst.console == "adb" {
		tty, err = vmimpl.OpenAdbConsole(inst.adbBin, inst.device)
	} else {
		tty, err = vmimpl.OpenConsole(inst.console)
	}
	if err != nil {
		return nil, nil, err
	}

	adbRpipe, adbWpipe, err := osutil.LongPipe()
	if err != nil {
		tty.Close()
		return nil, nil, err
	}
	if inst.debug {
		log.Logf(0, "starting: adb shell %v", command)
	}
	adb := osutil.Command(inst.adbBin, "-s", inst.device, "shell", "cd /data; "+command)
	adb.Stdout = adbWpipe
	adb.Stderr = adbWpipe
	if err := adb.Start(); err != nil {
		tty.Close()
		adbRpipe.Close()
		adbWpipe.Close()
		return nil, nil, fmt.Errorf("failed to start adb: %w", err)
	}
	adbWpipe.Close()

	var tee io.Writer
	if inst.debug {
		tee = os.Stdout
	}
	merger := vmimpl.NewOutputMerger(tee)
	merger.Add("console", tty)
	merger.Add("adb", adbRpipe)

	return vmimpl.Multiplex(adb, merger, tty, timeout, stop, inst.closed, inst.debug)
}

func (inst *instance) Diagnose(rep *report.Report) ([]byte, bool) {
	return nil, false
}
