// Copyright 2020 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 fuzz

import (
	"flag"
	"fmt"
	"io"
	"math/rand"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"testing"
	"time"
)

// Note: In order to avoid needing to mock out exec.Cmd or to have external
// program(s) act as mock subprocesses, we implement the subprocess mocks here
// in the main test binary (see TestDoProcessMock) and spawn a copy of ourself
// as a subprocess whenever mockCommand is called. A special environment
// variable is set to trigger the mocking behavior, and the first non-flag
// command-line argument is used as the command name so we know which specific
// behavior to emulate. Despite being misleadingly named process_test.go (which
// is necessary so that we can invoke TestDoProcessMock in the subprocess),
// this file is actually mostly process mocking.

// Drop-in replacement for exec.Command for use during testing.
func mockCommand(command string, args ...string) *exec.Cmd {
	// For ps, pass through directly
	if command == "ps" {
		return exec.Command(command, args...)
	}

	// Call ourself as the subprocess so we can mock behavior as appropriate
	argv := []string{"-logtostderr", "-test.run=TestDoProcessMock", "--", command}
	argv = append(argv, args...)

	selfPath, _ := filepath.Abs(os.Args[0])
	cmd := exec.Command(selfPath, argv...)
	cmd.Env = os.Environ()
	cmd.Env = append(cmd.Env, "MOCK_PROCESS=yes")
	// Ensure the subprocess CPRNG is seeded uniquely (but deterministically)
	cmd.Env = append(cmd.Env, fmt.Sprintf("RAND_SEED=%d", rand.Int63()))

	return cmd
}

// This is the actual implementation of mocked subprocesses.
// The name is a little confusing because it has to have the Test prefix
func TestDoProcessMock(t *testing.T) {
	if os.Getenv("MOCK_PROCESS") != "yes" {
		t.Skip("Not in a subprocess")
	}
	seed, err := strconv.ParseInt(os.Getenv("RAND_SEED"), 10, 64)
	if err != nil {
		t.Fatalf("Invalid CPRNG seed: %s", err)
	}
	rand.Seed(seed)

	cmd, args := flag.Arg(0), flag.Args()[1:]

	// Check all args for a special invalid path being passed along
	for _, arg := range args {
		if strings.Contains(arg, invalidPath) {
			fmt.Println("file not found")
			os.Exit(1)
		}
	}

	var out string
	var exitCode int
	var stayAlive bool
	switch filepath.Base(cmd) {
	case "echo":
		out = strings.Join(args, " ") + "\n"
		exitCode = 0
	case FakeQemuFailing:
		out = "qemu error message"
		exitCode = 1
	case FakeQemuSlow:
		stayAlive = true
		out = "welcome to qemu for turtles 🐢"
		exitCode = 0
	// The following utilities already had their args checked for invalid paths
	// above, so at this point we just need to touch an expected output file.
	// The contents are randomized to allow for simple change detection.
	case "cp":
		touchRandomFile(t, args[len(args)-1])
		exitCode = 0
	case "fvm":
		touchRandomFile(t, args[0])
		exitCode = 0
	case "zbi":
		found := false
		for j, arg := range args[:len(args)-1] {
			if arg == "-o" {
				touchRandomFile(t, args[j+1])
				found = true
			}
		}
		if !found {
			t.Fatalf("No output specified in zbi command args: %s", args)
		}
		exitCode = 0
	case "qemu-system-x86_64", "qemu-system-aarch64":
		stayAlive = true
		var logFile string
		// Check for a logfile specified in a serial parameter
		for j, arg := range args[:len(args)-1] {
			if arg != "-serial" {
				continue
			}
			parts := strings.SplitN(args[j+1], ":", 2)
			if parts[0] == "file" {
				logFile = parts[1]
			}
		}

		logWriter := os.Stdout
		if logFile != "" {
			outFile, err := os.Create(logFile)
			if err != nil {
				t.Fatalf("error creating qemu log file: %s", err)
			}
			defer outFile.Close()
			logWriter = outFile
		}
		io.WriteString(logWriter, "early boot\n")
		io.WriteString(logWriter, successfulBootMarker+"\n")

		// Output >100KB of additional data to ensure we handle large logs correctly
		filler := strings.Repeat("data", 1024/4)
		for j := 0; j < 100; j++ {
			logLine := fmt.Sprintf("%d: %s", j, filler)
			io.WriteString(logWriter, logLine)
		}

		// Write a final success marker
		io.WriteString(logWriter, lateBootMessage+"\n")

		exitCode = 0
	case "symbolizer":
		if err := fakeSymbolize(os.Stdin, os.Stdout); err != nil {
			t.Fatalf("failed during scan: %s", err)
		}

		exitCode = 0
	case "ffx":
		// Consume any leading flags and their parameters
		i := 0
		params := make(map[string]string)
		for i < len(args)-1 {
			if !strings.HasPrefix(args[i], "-") {
				break
			}
			params[args[i]] = args[i+1]
			i += 2
		}

		// Validate presence of target parameter, but then ignore it
		if _, ok := params["--target"]; !ok {
			t.Fatalf("ffx call missing target parameter")
		}

		// Validate isolate dir exists
		if isolateDir, ok := params["--isolate-dir"]; ok {
			if !fileExists(isolateDir) {
				t.Fatalf("isolate-dir %s doesn't exist", isolateDir)
			}
		} else {
			t.Fatalf("ffx call missing isolate-dir parameter")
		}

		command := args[i]
		args = args[i+1:]
		switch command {
		case "config":
			if args[0] != "set" {
				// Return an error, but avoid emitting what looks like a test
				// failure, because we know that TestFfxRunInvalidCommand will
				// call this and echo the output.
				out = fmt.Sprintf("invalid ffx config command: %s", args)
				exitCode = 1
			}
		case "daemon":
			if args[0] != "stop" {
				t.Fatalf("invalid ffx daemon command: %s", args)
			}
		case "target":
			if args[0] != "add" && args[0] != "remove" {
				t.Fatalf("invalid ffx target command: %s", args)
			}
		case "fuzz":
			stdout, outputDir := getFfxFuzzOutput(t, args)
			out = stdout

			// Perform any side-effect actions
			switch args[0] {
			case "minimize", "run":
				// Write fake artifact to output directory
				artifactDir := filepath.Join(outputDir, "artifacts")
				if err := os.Mkdir(artifactDir, os.ModeDir|0o700); err != nil {
					t.Fatalf("error making artifact dir: %s", err)
				}
				artifactPath := filepath.Join(artifactDir, "crash-1312")
				if err := os.WriteFile(artifactPath, []byte("data"), 0o600); err != nil {
					t.Fatalf("error writing artifact: %s", err)
				}
			case "fetch", "merge":
				// Fetch a fake live corpus into place
				corpusDir := filepath.Join(outputDir, "corpus")
				if err := os.Mkdir(corpusDir, os.ModeDir|0o700); err != nil {
					t.Fatalf("error making live corpus dir: %s", err)
				}
				touchRandomFile(t, filepath.Join(corpusDir, "a"))
				touchRandomFile(t, filepath.Join(corpusDir, "b"))
			}
			exitCode = 0
		default:
			t.Fatalf("invalid ffx command: %s", command)
		}
	default:
		exitCode = 127
	}

	os.Stdout.WriteString(out)
	if stayAlive {
		// Simulate a long-running process
		time.Sleep(10 * time.Second)
	}

	os.Exit(exitCode)
}

// This tests the subprocess mocking itself
func TestProcessMocking(t *testing.T) {
	// Enable subprocess mocking
	ExecCommand = mockCommand
	defer func() { ExecCommand = exec.Command }()

	cmd := NewCommand("echo", "it", "works")
	out, err := cmd.Output()
	if err != nil {
		t.Fatalf("Error running mock command: %s", err)
	}
	if string(out) != "it works\n" {
		t.Fatalf("Mock command returned unexpected output: %q", out)
	}

	cmd = NewCommand("ps", "-p", strconv.Itoa(os.Getpid()))
	out, err = cmd.Output()
	if err != nil {
		t.Fatalf("Error running mock command: %s (%q)", err, out)
	}
}
