// Copyright 2019 The Fuchsia 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 emulator

import (
	"archive/tar"
	"bufio"
	"bytes"
	"compress/gzip"
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"go.fuchsia.dev/fuchsia/tools/build"
	"go.fuchsia.dev/fuchsia/tools/lib/jsonutil"
	"go.fuchsia.dev/fuchsia/tools/qemu"
	"go.fuchsia.dev/fuchsia/tools/virtual_device"
	fvdpb "go.fuchsia.dev/fuchsia/tools/virtual_device/proto"
)

// Untar untars a tar.gz file into a directory.
func untar(dst string, src string) error {
	f, err := os.Open(src)
	if err != nil {
		return err
	}
	defer f.Close()

	gz, err := gzip.NewReader(f)
	if err != nil {
		return err
	}
	defer gz.Close()
	for tr := tar.NewReader(gz); ; {
		header, err := tr.Next()
		if err == io.EOF {
			return nil
		} else if err != nil {
			return err
		}

		path := filepath.Join(dst, header.Name)
		info := header.FileInfo()
		if info.IsDir() {
			if err := os.MkdirAll(path, info.Mode()); err != nil {
				return err
			}
		} else {
			if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
				return err
			}

			f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, info.Mode())
			if err != nil {
				return err
			}
			_, err = io.Copy(f, tr)
			f.Close()
			if err != nil {
				return err
			}
		}
	}
}

// Distribution is a collection of QEMU-related artifacts.
//
// Delete must be called once done with it.
type Distribution struct {
	testDataDir  string
	unpackedPath string
	Emulator     Emulator
}

// Arch is the architecture to emulate.
type Arch string

const (
	X64   Arch = "x64"
	Arm64 Arch = "arm64"
)

// Emulator is the emulator to use.
type Emulator int

const (
	Qemu Emulator = iota
	Femu
)

// Disk represents a single disk that will be attached to the virtual machine.
type Disk struct {
	Path string
	USB  bool
}

// Instance is a live emulator instance.
type Instance struct {
	cmd      *exec.Cmd
	piped    *exec.Cmd
	stdin    *bufio.Writer
	stdout   *bufio.Reader
	stderr   *bufio.Reader
	emulator Emulator
}

// DistributionParams is passed to UnpackFrom().
type DistributionParams struct {
	Emulator Emulator
}

// buildInfo carries information about the Fuchsia build.
//
// This is read from a file generated by BUILD.gn.
type buildInfo struct {
	// The path to the image.json manifest produced by the build.
	//
	// This path is relative to the file from which this struct was read.
	ImageManifestPath string

	// The build's target CPU architecture.
	TargetCPU string
}

// DefaultVirtualDevice returns a virtual device configuration for testing.
//
// The returned virtual device is compatible with the image manifest produced by a Fuchsia
// build for the specified architecture.
func DefaultVirtualDevice(arch string) *fvdpb.VirtualDevice {
	var arch_kernel_args []string
	// legacy is only supported for x64 arch.
	if arch == "x64" {
		arch_kernel_args = append(arch_kernel_args, "kernel.serial=legacy")
	}
	return &fvdpb.VirtualDevice{
		Name:   "default",
		Kernel: "qemu-kernel",
		Initrd: "zircon-a",
		Hw: &fvdpb.HardwareProfile{
			Arch:      arch,
			Mac:       "52:54:00:63:5e:7a",
			Ram:       "8K",
			CpuCount:  8,
			EnableKvm: arch == "x64",
		},
		KernelArgs: append(arch_kernel_args,
			"kernel.entropy-mixin=1420bb81dc0396b37cc2d0aa31bb2785dadaf9473d0780ecee1751afb5867564",
			"kernel.halt-on-panic=true",
			// Disable lockup detector heartbeats. In emulated environments, virtualized CPUs
			// may be starved or fail to execute in a timely fashion, resulting in apparent
			// lockups. See fxbug.dev/65990.
			"kernel.lockup-detector.heartbeat-period-ms=0",
			"kernel.lockup-detector.heartbeat-age-threshold-ms=0"),
	}
}

// UnpackFrom unpacks the emulator distribution.
//
// path is the path to host_x64/test_data containing the emulator.
// emulator is the emulator to unpack.
func UnpackFrom(path string, distroParams DistributionParams) (*Distribution, error) {
	// Since the emulator will be started from a different directory, make the base path
	// absolute.
	path, err := filepath.Abs(path)
	if err != nil {
		return nil, err
	}
	emulator_file := "qemu.tar.gz"
	if distroParams.Emulator == Femu {
		emulator_file = "femu.tar.gz"
	}
	archivePath := filepath.Join(path, "emulator", emulator_file)
	unpackedPath, err := ioutil.TempDir("", "emulator-distro")
	if err != nil {
		return nil, err
	}
	if err = untar(unpackedPath, archivePath); err != nil {
		os.RemoveAll(unpackedPath)
		return nil, err
	}
	return &Distribution{
		testDataDir:  path,
		unpackedPath: unpackedPath,
		Emulator:     distroParams.Emulator,
	}, nil
}

// Delete removes the emulator-related artifacts.
func (d *Distribution) Delete() error {
	return os.RemoveAll(d.unpackedPath)
}

func (d *Distribution) systemPath(arch Arch) string {
	if d.Emulator == Femu {
		// FEMU has one binary for all arches.
		return filepath.Join(d.unpackedPath, "emulator")
	}
	switch arch {
	case X64:
		return filepath.Join(d.unpackedPath, "bin", "qemu-system-x86_64")
	case Arm64:
		return filepath.Join(d.unpackedPath, "bin", "qemu-system-aarch64")
	}
	return ""
}

// TargetCPU returns the target CPU used by the build that produced this library.
func (d *Distribution) TargetCPU() (Arch, error) {
	buildinfo, err := d.loadBuildInfo()
	if err != nil {
		return X64, err
	}
	switch buildinfo.TargetCPU {
	case "x64":
		return X64, nil
	case "arm64":
		return Arm64, nil
	}
	return X64, fmt.Errorf("unknown target CPU: %s", buildinfo.TargetCPU)
}

func (d *Distribution) buildCommandLine(
	fvd *fvdpb.VirtualDevice,
	images build.ImageManifest,
) ([]string, error) {
	if d.Emulator == Femu {
		b := qemu.NewAEMUCommandBuilder()
		b.SetBinary(d.systemPath(Arch(fvd.Hw.Arch)))
		// Ask QEMU to emit a message on stderr once the VM is running
		// so we'll know whether QEMU has started or not.
		b.SetFlag("-trace", "enable=vm_state_notify")
		b.SetFlag("-nographic")
		if err := virtual_device.AEMUCommand(b, fvd, images); err != nil {
			return nil, err
		}
		return b.Build()
	}

	b := &qemu.QEMUCommandBuilder{}
	b.SetBinary(d.systemPath(Arch(fvd.Hw.Arch)))
	// Ask QEMU to emit a message on stderr once the VM is running
	// so we'll know whether QEMU has started or not.
	b.SetFlag("-trace", "enable=vm_state_notify")
	b.SetFlag("-nographic")
	if err := virtual_device.QEMUCommand(b, fvd, images); err != nil {
		return nil, err
	}
	return b.Build()

}

// Create creates an instance of the emulator with the given parameters.
func (d *Distribution) Create(fvd *fvdpb.VirtualDevice) (*Instance, error) {
	return d.create(
		func(args []string) *exec.Cmd { return exec.Command(args[0], args[1:]...) },
		fvd,
		nil,
	)
}

// CreateContext creates an instance of the emulator with the given parameters,
// passing through ctx to the underlying exec.Cmd.
func (d *Distribution) CreateContext(
	ctx context.Context,
	fvd *fvdpb.VirtualDevice,
) (*Instance, error) {
	return d.create(
		func(args []string) *exec.Cmd { return exec.CommandContext(ctx, args[0], args[1:]...) },
		fvd,
		nil,
	)
}

// CreateContextWithAuthorizedKeys creates an instance of the emulator, passing through ctx to the
// underlying exec.Cmd, and updating the virtual device's initrd to contain the specified authorized
// keys.
func (d *Distribution) CreateContextWithAuthorizedKeys(
	ctx context.Context,
	fvd *fvdpb.VirtualDevice,
	hostPathZbiBinary, hostPathAuthorizedKeys string,
) (*Instance, error) {
	return d.create(
		func(args []string) *exec.Cmd { return exec.CommandContext(ctx, args[0], args[1:]...) },
		fvd,
		&addAuthorizedKeys{
			hostPathZbiBinary:      hostPathZbiBinary,
			hostPathAuthorizedKeys: hostPathAuthorizedKeys,
		},
	)
}

type addAuthorizedKeys = struct {
	hostPathZbiBinary      string
	hostPathAuthorizedKeys string
}

// The create method is structured like this because the context docs explicitly warn
// against passing a nil Context, and exec.CommandContext(context.Background(), ...)
// is not equivalent to exec.Command(...).
func (d *Distribution) create(
	makeCmd func(args []string) *exec.Cmd,
	fvd *fvdpb.VirtualDevice,
	addAuthorizedKeys *addAuthorizedKeys,
) (*Instance, error) {
	images, err := d.loadImageManifest()
	if err != nil {
		return nil, err
	}

	if addAuthorizedKeys != nil {
		hostPathZbiBinary := addAuthorizedKeys.hostPathZbiBinary
		hostPathAuthorizedKeys := addAuthorizedKeys.hostPathAuthorizedKeys

		// This will get cleaned up by d.Delete().
		root, err := os.MkdirTemp(d.unpackedPath, "zbi-tmp-dir-*")
		if err != nil {
			return nil, fmt.Errorf("error making temp directory in %s: %w", d.unpackedPath, err)
		}

		if err := runZbi(runZbiArgs{
			imagesIWillMutateThis: images,
			workingDirectory:      root,
			hostPathZbiBinary:     hostPathZbiBinary,
			initrdName:            fvd.Initrd,
			zbiArgs: []string{
				"--entry",
				fmt.Sprintf("data/ssh/authorized_keys=%s", hostPathAuthorizedKeys),
			},
		}); err != nil {
			if rmErr := os.RemoveAll(root); rmErr != nil {
				log.Println(rmErr)
			}
			return nil, err
		}
	}

	args, err := d.buildCommandLine(fvd, images)
	if err != nil {
		return nil, err
	}

	fmt.Printf("Running %s %s\n", args[0], args[1:])

	i := &Instance{
		cmd:      makeCmd(args),
		emulator: d.Emulator,
	}
	// QEMU looks in the cwd for some specially named files, in particular
	// multiboot.bin, so avoid picking those up accidentally. See
	// https://fxbug.dev/53751.
	// TODO(fxbug.dev/58804): Remove this.
	i.cmd.Dir = "/"

	return i, nil
}

type runZbiArgs struct {
	imagesIWillMutateThis []build.Image
	workingDirectory      string
	hostPathZbiBinary     string
	initrdName            string
	zbiArgs               []string
}

func runZbi(args runZbiArgs) error {
	images := args.imagesIWillMutateThis
	root := args.workingDirectory

	oldZBIPath := ""
	newZBIPath := filepath.Join(root, "a.zbi")

	// Replace the ZBI in the image manifest with our modified one.
	for i, image := range images {
		if image.Name == args.initrdName && image.Type == "zbi" {
			oldZBIPath = image.Path
			images[i].Path = newZBIPath
			break
		}
	}

	cmd := exec.Command(
		args.hostPathZbiBinary,
		append([]string{"-o", newZBIPath, oldZBIPath}, args.zbiArgs...)...)

	var stderrBuf bytes.Buffer
	cmd.Stderr = &stderrBuf
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("error running %q: %w; stderr:\n%s", cmd, err, stderrBuf.String())
	}
	return nil
}

// RunNonInteractive runs an instance of the emulator that runs a single command and
// returns the log that results from doing so.
//
// This mode is non-interactive and is intended specifically to test the case
// where the serial port has been disabled. The following modifications are
// made to the emulator invocation compared with Create()/Start():
//
//  - amalgamate the given ZBI into a larger one that includes an additional
//    entry of a script which includes commands to run.
//  - that script mounts a disk created on the host in /tmp, and runs the
//    given command with output redirected to a file also on the /tmp disk
//  - the script triggers shutdown of the machine
//  - after emulator shutdown, the log file is extracted and returned.
//
// In order to achieve this, here we need to create the host minfs
// file system, write the commands to run, build the augmented .zbi to
// be used to boot. We then use Start() and wait for shutdown.
// Finally, extract and return the log from the minfs disk.
func (d *Distribution) RunNonInteractive(
	toRun, hostPathMinfsBinary, hostPathZbiBinary string,
	fvd *fvdpb.VirtualDevice,
) (string, string, error) {
	root, err := ioutil.TempDir("", "qemu")
	if err != nil {
		return "", "", err
	}
	log, logerr, err := d.runNonInteractive(root, toRun, hostPathMinfsBinary, hostPathZbiBinary, fvd)
	if err2 := os.RemoveAll(root); err == nil {
		err = err2
	}
	return log, logerr, err
}

func (d *Distribution) runNonInteractive(
	root, toRun, hostPathMinfsBinary, hostPathZbiBinary string,
	fvd *fvdpb.VirtualDevice,
) (string, string, error) {
	// Write runcmds that mounts the results disk, runs the requested command, and
	// shuts down.
	script := `waitfor class=block topo=/dev/pci-00:06.0/virtio-block/block timeout=60000
mount /dev/pci-00:06.0/virtio-block/block /mnt/testdata-fs
` + toRun + ` 2>/mnt/testdata-fs/err.txt >/mnt/testdata-fs/log.txt
umount /mnt/testdata-fs
dm poweroff
`
	runcmds := filepath.Join(root, "runcmds.txt")
	if err := ioutil.WriteFile(runcmds, []byte(script), 0666); err != nil {
		return "", "", err
	}
	// Make a minfs filesystem to mount in the target.
	fs := filepath.Join(root, "a.fs")
	cmd := exec.Command(hostPathMinfsBinary, fs+"@100M", "mkfs")
	if err := cmd.Run(); err != nil {
		return "", "", err
	}

	images, err := d.loadImageManifest()
	if err != nil {
		return "", "", err
	}

	if err := runZbi(runZbiArgs{
		imagesIWillMutateThis: images,
		workingDirectory:      root,
		hostPathZbiBinary:     hostPathZbiBinary,
		initrdName:            fvd.Initrd,
		zbiArgs:               []string{"-e", "runcmds=" + runcmds},
	}); err != nil {
		return "", "", err
	}

	fvd.KernelArgs = append(fvd.KernelArgs, "zircon.autorun.boot=/boot/bin/sh+/boot/runcmds")

	// Add the temporary disk at 00:06.0. This follows how infra runs qemu with an extra
	// disk via botanist.
	fvd.Drive = &fvdpb.Drive{
		Id:         "resultdisk",
		Image:      fs,
		IsFilename: true,
		PciAddress: "6.0",
	}

	args, err := d.buildCommandLine(fvd, images)
	if err != nil {
		return "", "", err
	}

	fmt.Printf("Running non-interactive %s %s\n", args[0], args[1:])

	cmd = exec.Command(args[0], args[1:]...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	// QEMU looks in the cwd for some specially named files, in particular
	// multiboot.bin, so avoid picking those up accidentally. See
	// https://fxbug.dev/53751.
	// TODO(fxbug.dev/58804): Remove this.
	cmd.Dir = "/"
	if err := cmd.Start(); err != nil {
		return "", "", err
	}
	defer cmd.Process.Kill()
	if err := cmd.Wait(); err != nil {
		return "", "", err
	}

	log := filepath.Join(root, "log.txt")
	logerr := filepath.Join(root, "err.txt")
	cmd = exec.Command(hostPathMinfsBinary, fs, "cp", "::/log.txt", log)
	if err := cmd.Run(); err != nil {
		return "", "", err
	}
	cmd = exec.Command(hostPathMinfsBinary, fs, "cp", "::/err.txt", logerr)
	if err := cmd.Run(); err != nil {
		return "", "", err
	}

	retLog, err := ioutil.ReadFile(log)
	if err != nil {
		return "", "", err
	}
	retErr, err := ioutil.ReadFile(logerr)
	if err != nil {
		return "", "", err
	}
	fmt.Printf("===== %s non-interactive run stdout =====\n%s\n", toRun, retLog)
	fmt.Printf("===== %s non-interactive run stderr =====\n%s\n", toRun, retErr)
	fmt.Printf("===== %s end =====\n", toRun)
	return string(retLog), string(retErr), nil
}

// Decodes the buildinfo.ini file generated by BUILD.gn
func (d *Distribution) loadBuildInfo() (*buildInfo, error) {
	var buildinfo buildInfo

	path := filepath.Join(d.testDataDir, "emulator", "buildinfo.ini")
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("read %q: %w", path, err)
	}

	scanner := bufio.NewScanner(bytes.NewReader(data))
	for scanner.Scan() {
		line := scanner.Text()
		if strings.TrimSpace(line) == "" {
			continue
		}

		kv := strings.SplitN(line, "=", 2)
		if len(kv) != 2 {
			return nil, fmt.Errorf("invalid buildinfo line: %q", line)
		}
		switch kv[0] {
		case "image_manifest_path":
			buildinfo.ImageManifestPath = kv[1]
		case "target_cpu":
			buildinfo.TargetCPU = kv[1]
		default:
			return nil, fmt.Errorf("unknown buildinfo key: %q", kv[0])
		}
	}

	return &buildinfo, nil
}

func (d *Distribution) loadImageManifest() (build.ImageManifest, error) {
	buildinfo, err := d.loadBuildInfo()
	if err != nil {
		return nil, err
	}

	var images build.ImageManifest

	// ImageManifestPath is given as a relative path from test_data/emulator.
	imageManifestPath := filepath.Clean(
		filepath.Join(d.testDataDir, "emulator", buildinfo.ImageManifestPath),
	)
	if err := jsonutil.ReadFromFile(imageManifestPath, &images); err != nil {
		return nil, fmt.Errorf("json read %q: %w", imageManifestPath, err)
	}

	// Patch each image in the manifest to have an absolute path. The paths are already
	// relative to the image manifest.
	imageManifestDir := filepath.Dir(imageManifestPath)
	for i := range images {
		if !filepath.IsAbs(images[i].Path) {
			images[i].Path = filepath.Join(imageManifestDir, images[i].Path)
		}
	}

	return images, nil
}

// Start the emulator instance.
func (i *Instance) Start() error {
	return i.StartPiped(nil)
}

// StartPiped starts the emulator instance with stdin/stdout piped through a
// different process.
//
// Assumes that the stderr from the piped process should replace the stdout
// from the emulator.
func (i *Instance) StartPiped(piped *exec.Cmd) error {
	stdin, err := i.cmd.StdinPipe()
	if err != nil {
		return err
	}
	stdout, err := i.cmd.StdoutPipe()
	if err != nil {
		return err
	}
	stderr, err := i.cmd.StderrPipe()
	if err != nil {
		return err
	}

	if piped != nil {
		piped.Stdin = stdout
		piped.Stdout = stdin
		pipedStderr, err := piped.StderrPipe()
		if err != nil {
			return err
		}
		i.stdout = bufio.NewReader(pipedStderr)
		i.stderr = bufio.NewReader(stderr)
		if err = piped.Start(); err != nil {
			return err
		}
		i.piped = piped
	} else {
		i.stdin = bufio.NewWriter(stdin)
		i.stdout = bufio.NewReader(stdout)
		i.stderr = bufio.NewReader(stderr)
	}

	startErr := i.cmd.Start()

	// Look for very early log message to validate that the emulator likely started
	// correctly. Loop for a while to give the emulator a chance to boot.
	fmt.Println("Checking for QEMU boot...")
	for j := 0; j < 100; j++ {

		if i.emulator == Femu {
			// FEMU isn't built with support for outputting trace events.
			// Instead we look for a message that occurs very early during Zircon boot.
			if i.checkForLogMessage(i.stdout, "welcome to Zircon") == nil {
				break
			}
		} else {
			// The flag `-trace enable=vm_state_notify` will cause qemu to
			// print this message early in boot.
			if i.checkForLogMessage(i.stderr, "vm_state_notify running") == nil {
				break
			}
		}

		time.Sleep(100 * time.Millisecond)
	}

	return startErr
}

// Kill terminates the emulator instance.
func (i *Instance) Kill() error {
	var err error
	if i.piped != nil {
		err = i.piped.Process.Kill()
	}
	if err2 := i.cmd.Process.Kill(); err2 != nil {
		return err2
	}
	return err
}

func printWhileWait(r *bufio.Reader, proc *os.Process) (*os.ProcessState, error) {
	stop := make(chan struct{})
	defer close(stop)
	go func() {
		for {
			select {
			case <-stop:
				return
			default:
				if line, err := r.ReadString('\n'); err == nil {
					fmt.Print(line)
				}
			}
		}
	}()

	ps, err := proc.Wait()
	return ps, err
}

// Wait for the emulator instance to terminate
func (i *Instance) Wait() (*os.ProcessState, error) {
	if i.piped != nil {
		if ps, err := printWhileWait(i.stdout, i.piped.Process); err != nil {
			return ps, err
		}
	}
	return printWhileWait(i.stdout, i.cmd.Process)
}

// RunCommand runs the given command in the serial console for the emulator
// instance.
func (i *Instance) RunCommand(cmd string) error {
	if _, err := fmt.Fprintf(i.stdin, "%s\n", cmd); err != nil {
		return err
	}
	return i.stdin.Flush()
}

// WaitForLogMessage reads log messages from the emulator instance until it reads a
// message that contains the given string.
func (i *Instance) WaitForLogMessage(msg string) error {
	return i.WaitForLogMessages([]string{msg})
}

// WaitForLogMessages reads log messages from the emulator instance until it reads all
// message in |msgs|. The log messages can appear in *any* order. Only one
// expected message from |msgs| is retired per matching actual message even if
// multiple messages from |msgs| match the log line.
func (i *Instance) WaitForLogMessages(msgs []string) error {
	return i.checkForLogMessages(i.stdout, msgs)
}

// WaitForAnyLogMessage reads log messages from the emulator instance looking for any line that
// contains a message from msgs.
// Returns the first message that was found, or an error.
func (i *Instance) WaitForAnyLogMessage(msgs ...string) (string, error) {
	for {
		line, err := i.stdout.ReadString('\n')
		if err != nil {
			i.printStderr()
			return "", err
		}
		for _, msg := range msgs {
			if strings.Contains(line, msg) {
				return msg, nil
			}
		}
	}
}

// WaitForLogMessageAssertNotSeen is the same as WaitForLogMessage() but with
// the addition that it will return an error if |notSeen| is contained in a
// retrieved message.
func (i *Instance) WaitForLogMessageAssertNotSeen(msg string, notSeen string) error {
	for {
		line, err := i.stdout.ReadString('\n')
		if err != nil {
			i.printStderr()
			return fmt.Errorf("failed to find: %q: %w", msg, err)
		}
		fmt.Print(line)
		if strings.Contains(line, msg) {
			return nil
		}
		if strings.Contains(line, notSeen) {
			return fmt.Errorf("found in output: %q", notSeen)
		}
	}
}

// AssertLogMessageNotSeenWithinTimeout will fail if |notSeen| is seen within the
// |timeout| period. This function will timeout as success if more than |timeout| has
// passed without seeing |notSeen|.
func (i *Instance) AssertLogMessageNotSeenWithinTimeout(
	notSeen string,
	timeout time.Duration,
) error {
	// ReadString is blocking, we need to make sure it respects the global timeout.
	seen := make(chan struct{})
	stop := make(chan struct{})
	defer close(stop)
	go func() {
		defer close(seen)
		for {
			select {
			case <-stop:
				return
			default:
				if line, err := i.stdout.ReadString('\n'); err == nil {
					if strings.Contains(line, notSeen) {
						seen <- struct{}{}
						return
					}
				}
			}
		}
	}()
	select {
	case <-seen:
		return fmt.Errorf("found in output: %q", notSeen)
	case <-time.After(timeout):
		return nil
	}
}

// Reset display: ESC c
// Reset screen mode: ESC [ ? 7 l
// Move cursor home: ESC [ 2 J
// All text attributes off: ESC [ 0 m
const emuClearPrefix = "\x1b\x63\x1b\x5b\x3f\x37\x6c\x1b\x5b\x32\x4a\x1b\x5b\x30\x6d"

// Reads all messages from |b| and tests if |msg| appears. Returns error if any.
func (i *Instance) checkForLogMessage(b *bufio.Reader, msg string) error {
	return i.checkForLogMessages(b, []string{msg})
}

// printStderr prints all the lines from the instance's stderr stream.
func (i *Instance) printStderr() {
	fmt.Printf("printing stderr...\n")
	for {
		stderr, err := i.stderr.ReadString('\n')
		if err != nil {
			return
		}
		fmt.Print(stderr)
	}
}

// Reads all messages from |b| and tests if all messages of |msgs| appear in *any* order. Returns
// error if any.
func (i *Instance) checkForLogMessages(b *bufio.Reader, msgs []string) error {
	for {
		line, err := b.ReadString('\n')
		if err != nil {
			i.printStderr()
			return err
		}

		// Drop the clearing preamble as it makes it difficult to see output
		// when there's multiple emulator runs in a single binary.
		toPrint := line
		if strings.HasPrefix(toPrint, emuClearPrefix) {
			toPrint = toPrint[len(emuClearPrefix):]
		}
		fmt.Print(toPrint)
		for i, msg := range msgs {
			if strings.Contains(line, msg) {
				msgs = append(msgs[:i], msgs[i+1:]...)
				if len(msgs) == 0 {
					return nil
				}
				break
			}
		}
	}
}

// CaptureLinesContaining returns all the lines that contain the given msg, up until a line
// containing stop is found.
func (i *Instance) CaptureLinesContaining(msg string, stop string) ([]string, error) {
	res := []string{}
	for {
		line, err := i.stdout.ReadString('\n')
		if err != nil {
			i.printStderr()
			return nil, err
		}
		if strings.Contains(line, msg) {
			res = append(res, line)
		}
		if strings.Contains(line, stop) {
			return res, nil
		}
	}
}
