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

import (
	"context"
	"crypto/rand"
	"encoding/hex"
	"net"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"
	"time"

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

// The default nodename given to an target with the default QEMU MAC address.
const defaultNodename = "fuchsia-5254-0012-3456"

func toolPath(t *testing.T, name string) string {
	return filepath.Join(execDir(t), "test_data", "limited_netsvc", name)
}

func cmdWithTimeout(t *testing.T, ctx context.Context, shouldWork bool, name string, arg ...string) {
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()

	cmd := exec.CommandContext(ctx, name, arg...)

	out, err := cmd.Output()

	if shouldWork && ctx.Err() == context.DeadlineExceeded {
		t.Errorf("%s timed out %s, err=%s", name, out, err)
	} else if shouldWork && err != nil {
		t.Errorf("%s failed %s, err=%s", name, out, err)
	} else if !shouldWork && err == nil {
		t.Errorf("%s succeeded but shouldn't have %s, err=%s", name, out, err)
	} else {
		expected := "succeeded"
		if !shouldWork {
			expected = "failed"
		}
		t.Logf("%s %s as expected", name, expected)
	}
}

func attemptNetcp(t *testing.T, ctx context.Context, shouldWork bool) {
	cmdWithTimeout(
		t,
		ctx,
		shouldWork,
		toolPath(t, "netcp"),
		defaultNodename+":/boot/kernel/vdso/stable",
		"/tmp/vdso",
	)
}

func randomTokenAsString(t *testing.T) string {
	b := [32]byte{}
	if _, err := rand.Read(b[:]); err != nil {
		t.Fatal(err)
	}
	return hex.EncodeToString(b[:])
}

func attemptNetruncmd(t *testing.T, ctx context.Context, i *emulatortest.Instance, shouldWork bool) {
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()

	name := toolPath(t, "netruncmd")
	tokenFromNetruncmd := randomTokenAsString(t)
	cmd := exec.CommandContext(ctx, name, defaultNodename, tokenFromNetruncmd)

	if err := cmd.Run(); err != nil {
		t.Errorf("%s failed to run? err=%s", name, err)
	}

	time.Sleep(time.Second)
	tokenFromSerial := randomTokenAsString(t)
	i.RunCommand("echo '" + tokenFromSerial + "'")

	if shouldWork {
		// If netruncmd works, we should get the token echo'd by netruncmd first,
		// then the terminator (which is sent over serial).
		i.WaitForLogMessage(tokenFromNetruncmd)
		i.WaitForLogMessage(tokenFromSerial)
		t.Logf("%s succeeded as expected", name)
	} else {
		// If netruncmd isn't working, we must not see the netruncmd token, and
		// should only get the serial token.
		i.WaitForLogMessageAssertNotSeen(tokenFromSerial, tokenFromNetruncmd)
		t.Logf("%s failed as expected", name)
	}
}

func attemptNetls(t *testing.T, ctx context.Context, shouldWork bool) {
	cmdWithTimeout(t, ctx, shouldWork, toolPath(t, "netls"))
}

func attemptNetaddr(t *testing.T, ctx context.Context, shouldWork bool) {
	cmdWithTimeout(t, ctx, shouldWork, toolPath(t, "netaddr"))
}

func attemptTftp(t *testing.T, ctx context.Context, shouldWork bool) {
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()

	addr, err := netutil.GetNodeAddress(ctx, defaultNodename)
	if err != nil {
		t.Fatal(err)
		return
	}

	tftp, err := tftp.NewClient(&net.UDPAddr{
		IP:   addr.IP,
		Port: tftp.ClientPort,
		Zone: addr.Zone,
	}, 0, 0)
	if err != nil {
		t.Fatal(err)
		return
	}

	reader := strings.NewReader("123456789")
	if err := tftp.Write(ctx, "/tmp/test", reader, reader.Size()); shouldWork {
		if err == nil {
			t.Log("tftp write succeeded as expected")
		} else {
			t.Fatalf("tftp write failed, but expected to succeed: %s", err)
		}
	} else {
		if err == nil {
			t.Fatal("tftp write expected to fail, but succeeded")
		} else {
			t.Logf("tftp write failed as expected: %s", err)
		}
	}
}

func attemptLoglistener(t *testing.T, ctx context.Context, shouldWork bool) {
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()

	name := toolPath(t, "loglistener")
	cmd := exec.CommandContext(ctx, name, defaultNodename)

	out, err := cmd.Output()
	if err != nil && err.Error() != "signal: killed" {
		t.Errorf("%s: %s", name, err)
		return
	}

	if shouldWork {
		if !strings.Contains(string(out), "netsvc: start") {
			t.Errorf("%s didn't find 'netsvc: start' in retrieved log: %s, err=%s", name, out, err)
		} else {
			t.Logf("%s succeeded as expected", name)
		}
	} else {
		// Should only get the "listening..." line, but no other output.
		if len(strings.Split(string(out), "\n")) != 1 {
			t.Errorf("%s incorrectly received log\n", name)
			t.Errorf("got: %s", string(out))
		} else {
			t.Logf("%s failed as expected", name)
		}
	}
}

func setupQemu(t *testing.T, ctx context.Context, appendCmdline []string, modeString string) *emulatortest.Instance {
	exDir := execDir(t)
	distro := emulatortest.UnpackFrom(t, filepath.Join(exDir, "test_data"), emulator.DistributionParams{
		Emulator: emulator.Qemu,
	})
	arch := distro.TargetCPU()
	device := emulator.DefaultVirtualDevice(string(arch))
	device.KernelArgs = append(device.KernelArgs, appendCmdline...)

	// Note: To run this test locally on linux, you must create the TAP interface:
	// $ sudo ip tuntap add mode tap qemu
	device.Hw.NetworkDevices = append(device.Hw.NetworkDevices, &fvdpb.Netdev{
		Id:     "qemu",
		Kind:   "tap",
		Device: &fvdpb.Device{Model: "virtio-net-pci"},
	})
	i := distro.CreateContext(ctx, device)
	i.Start()

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

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

func TestNetsvcAllFeatures(t *testing.T) {
	cmdline := []string{"netsvc.all-features=true"}
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	i := setupQemu(t, ctx, cmdline, "full")

	// Setting all-features to true means netsvc will work normally, and all
	// features should work.
	attemptLoglistener(t, ctx, true)
	attemptNetaddr(t, ctx, true)
	attemptNetcp(t, ctx, true)
	attemptNetls(t, ctx, true)
	attemptNetruncmd(t, ctx, i, true)
	attemptTftp(t, ctx, true)
}

func TestNetsvcAllFeaturesWithNodename(t *testing.T) {
	cmdline := []string{"netsvc.all-features=true", "zircon.nodename=" + defaultNodename}
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	i := setupQemu(t, ctx, cmdline, "full")

	// Setting all-features to true means netsvc will work normally, and all
	// features should work.
	attemptLoglistener(t, ctx, true)
	attemptNetaddr(t, ctx, true)
	attemptNetcp(t, ctx, true)
	attemptNetls(t, ctx, true)
	attemptNetruncmd(t, ctx, i, true)
	attemptTftp(t, ctx, true)
}

func TestNetsvcLimited(t *testing.T) {
	cmdline := []string{"netsvc.all-features=false"}
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	i := setupQemu(t, ctx, cmdline, "limited")

	// Explicitly setting all-features to false should be the same as default, and
	// most operations should fail.
	attemptLoglistener(t, ctx, false)
	attemptNetaddr(t, ctx, true)
	attemptNetcp(t, ctx, false)
	attemptNetls(t, ctx, true)
	attemptNetruncmd(t, ctx, i, false)
	attemptTftp(t, ctx, false)
}

func execDir(t *testing.T) string {
	ex, err := os.Executable()
	if err != nil {
		t.Fatal(err)
	}
	return filepath.Dir(ex)
}
