// 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 bootservertest includes common code to write smoke tests for
// bootserver_old.
package bootservertest

import (
	"bufio"
	"context"
	"flag"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"strings"
	"testing"
	"time"

	"go.fuchsia.dev/fuchsia/tools/emulator"
	"go.fuchsia.dev/fuchsia/tools/emulator/emulatortest"
	fvdpb "go.fuchsia.dev/fuchsia/tools/virtual_device/proto"
)

var hostDir = map[string]string{"arm64": "host_arm64", "amd64": "host_x64"}[runtime.GOARCH]

func testDataDir() string {
	base := filepath.Join("..", "..", "..", "..")
	c, err := os.ReadFile(filepath.Join(base, ".fx-build-dir"))
	if err != nil {
		return ""
	}
	return filepath.Join(base, strings.TrimSpace(string(c)), hostDir, "test_data")
}

// TestDataDir is the location to test data files.
//
//   - In "go test" mode, it's relative to this directory.
//   - In "fx test" mode, it's relative to the build directory (out/default).
var TestDataDir = flag.String("test_data_dir", testDataDir(), "Path to test_data/; only used in GN build")

// DefaultNodename is the default nodename given to an target with the default
// QEMU MAC address.
const DefaultNodename = "swarm-donut-petri-acre"

// ToolPath returns the full path to a tool.
func ToolPath(t *testing.T, name string) string {
	p, err := filepath.Abs(filepath.Join(*TestDataDir, "bootserver_tools", name))
	if err != nil {
		t.Fatal(err)
	}
	return p
}

// CmdWithOutput returns a command and returns stdout.
func CmdWithOutput(t *testing.T, name string, arg ...string) []byte {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	cmd := exec.CommandContext(ctx, name, arg...)
	out, err := cmd.Output()
	if err != nil {
		t.Errorf("%s failed %s, err=%s", name, out, err)
		return nil
	}
	return out
}

// LogMatch is one pattern to search for.
type LogMatch struct {
	Pattern     string
	ShouldMatch bool
}

func matchPattern(t *testing.T, pattern string, reader *bufio.Reader) bool {
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				t.Logf("matchPattern(%q): EOF", pattern)
				return false
			}
			t.Fatal(err)
		}
		if strings.Contains(line, pattern) {
			t.Logf("matchPattern(%q): true", pattern)
			return true
		}
		t.Logf("matchPattern(%q): ignored %q", pattern, line)
	}
}

// CmdSearchLog searches for a patterns in stderr.
func CmdSearchLog(t *testing.T, logPatterns []LogMatch, name string, arg ...string) {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	cmd := exec.CommandContext(ctx, name, arg...)
	cmderr, err := cmd.StderrPipe()
	if err != nil {
		t.Errorf("Failed to stderr %s", err)
	}
	readerErr := bufio.NewReader(cmderr)
	if err := cmd.Start(); err != nil {
		t.Errorf("Failed to start %s", err)
	}

	found := false
	for _, logPattern := range logPatterns {
		match := matchPattern(t, logPattern.Pattern, readerErr)
		if match != logPattern.ShouldMatch {
			found = false
			t.Errorf("Log pattern \"%s\" mismatch. Expected - %t, actual - %t",
				logPattern.Pattern, logPattern.ShouldMatch, match)
			break
		}
		found = true
	}

	if err := cmd.Wait(); err != nil {
		t.Logf("Failed to wait on task %s", err)
	}

	if ctx.Err() == context.DeadlineExceeded {
		t.Errorf("%s timed out err=%s", name, ctx.Err())
	} else if !found {
		t.Errorf("%s failed to match logs", name)
	} else {
		t.Logf("%s worked as expected", name)
	}
}

// AttemptPaveNoBind attempts to initiate a pave.
func AttemptPaveNoBind(t *testing.T, shouldWork bool) {
	// Get the node ipv6 address.
	out := CmdWithOutput(t, ToolPath(t, "netls"))
	// Extract the ipv6 from the netls output
	regexString := DefaultNodename + ` \((?P<ipv6>.*)\)`
	match := regexp.MustCompile(regexString).FindStringSubmatch(string(out))
	if len(match) != 2 {
		t.Errorf("Node %s not found in netls output - %s", DefaultNodename, out)
		return
	}

	var logPattern []LogMatch
	if shouldWork {
		paveWorksPattern := []LogMatch{
			{"Sending request to ", true},
			{"Received request from ", true},
			{"Proceeding with nodename ", true},
			{"Transfer starts", true},
		}
		logPattern = paveWorksPattern
	} else {
		paveFailsPattern := []LogMatch{
			{"Sending request to ", true},
			{"Received request from ", false},
			{"Proceeding with nodename ", false},
			{"Transfer starts", false},
		}
		logPattern = paveFailsPattern
	}

	CmdSearchLog(
		t, logPattern,
		ToolPath(t, "bootserver"), "--fvm", "\"dummy.blk\"",
		"--no-bind", "-a", match[1], "-1", "--fail-fast")
}

// StartQemu starts a QEMU instance with the given kernel commandline args.
func StartQemu(t *testing.T, appendCmdline []string, modeString string) *emulatortest.Instance {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}
	distro := emulatortest.UnpackFrom(t, *TestDataDir, emulator.DistributionParams{
		Emulator: emulator.Qemu,
	})
	arch := distro.TargetCPU()
	device := emulator.DefaultVirtualDevice(string(arch))
	device.KernelArgs = append(device.KernelArgs, appendCmdline...)
	device.KernelArgs = append(device.KernelArgs, "zircon.nodename="+DefaultNodename)

	// To run locally on linux, you need to configure a tuntap interface:
	// $ sudo ip add mode tap qemu user `whoami`
	// $ sudo ip link set qemu up
	device.Hw.NetworkDevices = append(device.Hw.NetworkDevices, &fvdpb.Netdev{
		Id:     "qemu",
		Kind:   "tap",
		Device: &fvdpb.Device{Model: "virtio-net-pci"},
	})
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	instance := distro.CreateContext(ctx, device)
	instance.Start()

	// Make sure netsvc in expected mode.
	instance.WaitForLogMessage("netsvc: running in " + modeString + " mode")

	// Make sure netsvc is booted.
	instance.WaitForLogMessage("netsvc: start")
	return instance
}
