// 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 (
	"bytes"
	"os"
	"os/exec"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
)

func TestQemuLauncherHandle(t *testing.T) {
	launcher := &QemuLauncher{Pid: 4141, TmpDir: "/tmp/woof"}

	handle, err := NewHandleWithData(HandleData{launcher: launcher})
	if err != nil {
		t.Fatalf("error creating handle: %s", err)
	}
	defer handle.Release()

	// Note: we don't serialize here because that is covered by handle tests

	build, _ := newMockBuild()

	reloadedLauncher, err := loadLauncherFromHandle(build, handle)
	if err != nil {
		t.Fatalf("error loading launcher from handle: %s", err)
	}

	ql, ok := reloadedLauncher.(*QemuLauncher)
	if !ok {
		t.Fatalf("incorrect launcher type")
	}

	if diff := cmp.Diff(launcher, ql, cmpopts.IgnoreUnexported(QemuLauncher{})); diff != "" {
		t.Fatalf("incorrect data in reloaded launcher (-want +got):\n%s", diff)
	}
}

func TestIncompleteQemuLauncherHandle(t *testing.T) {
	// Construct an object that isn't fully initialized
	launcher := &QemuLauncher{Pid: 4141}

	handle, err := NewHandleWithData(HandleData{launcher: launcher})
	if err != nil {
		t.Fatalf("error creating handle: %s", err)
	}
	defer handle.Release()

	if _, err := loadConnectorFromHandle(handle); err == nil {
		t.Fatalf("expected error, but succeeded")
	}
}

func TestQemuLauncherWithMissingDeps(t *testing.T) {
	// Enable subprocess mocking
	ExecCommand = mockCommand
	defer func() { ExecCommand = exec.Command }()

	for _, dep := range []string{"zbi", "fvm", "blk", "zbitool", "qemu", "kernel"} {
		// This awkward error-discarding and casting is due to the need for the
		// signature of newMockBuild to match the other Build-creating functions
		build, _ := newMockBuild()
		brokenBuild := build.(*mockBuild)
		defer os.RemoveAll(brokenBuild.enableQemu(t, FakeQemuNormal))

		brokenBuild.paths[dep] = invalidPath
		launcher := NewQemuLauncher(build)
		if _, err := launcher.Start(); err == nil {
			t.Fatalf("Expected error launching with missing %q dep but succeeded", dep)
		}

		expectPathAbsent(t, launcher.TmpDir)
	}
}

func TestQemuLauncherWithQemuFailure(t *testing.T) {
	// Enable subprocess mocking
	ExecCommand = mockCommand
	defer func() { ExecCommand = exec.Command }()

	build, _ := newMockBuild()
	defer os.RemoveAll(build.(*mockBuild).enableQemu(t, FakeQemuFailing))

	launcher := NewQemuLauncher(build)
	if _, err := launcher.Start(); err == nil {
		t.Fatalf("Expected error launching with failing qemu but succeeded")
	}

	expectPathAbsent(t, launcher.TmpDir)
}

func TestQemuLauncherWithQemuTimeout(t *testing.T) {
	// Enable subprocess mocking
	ExecCommand = mockCommand
	defer func() { ExecCommand = exec.Command }()

	build, _ := newMockBuild()
	defer os.RemoveAll(build.(*mockBuild).enableQemu(t, FakeQemuSlow))

	launcher := NewQemuLauncher(build)
	launcher.timeout = 10 * time.Millisecond
	if _, err := launcher.Start(); err == nil {
		t.Fatalf("Expected error launching with slow qemu but succeeded")
	}

	if running, err := launcher.IsRunning(); err != nil || running {
		t.Fatalf("expected qemu to be killed after timeout")
	}

	expectPathAbsent(t, launcher.TmpDir)
}

// Helper for detecting changes in files generated by Prepare
func getFileHashes(t *testing.T, q *QemuLauncher) map[string][]byte {
	hashes := make(map[string][]byte)
	for _, path := range []string{q.initrd, q.extendedBlk, q.sshKey, q.sshPublicKey} {
		hashes[path] = getFileHash(t, path)
	}
	return hashes
}

func TestQemuLauncherPrepare(t *testing.T) {
	// Enable subprocess mocking
	ExecCommand = mockCommand
	defer func() { ExecCommand = exec.Command }()

	build, _ := newMockBuild()
	launcher := NewQemuLauncher(build)

	if err := launcher.Prepare(); err != nil {
		t.Fatalf("Error preparing launcher: %s", err)
	}

	defer launcher.Kill()

	origFileHashes := getFileHashes(t, launcher)

	// Nothing should change if re-run
	if err := launcher.Prepare(); err != nil {
		t.Fatalf("Error re-preparing launcher: %s", err)
	}

	fileHashes := getFileHashes(t, launcher)

	if diff := cmp.Diff(origFileHashes, fileHashes); diff != "" {
		t.Fatalf("Prepare was not idempotent (-want +got):\n%s", diff)
	}

	// Check for regeneration of SSH key when necessary
	if err := os.Remove(launcher.sshKey); err != nil {
		t.Fatalf("Error deleting ssh key: %s", err)
	}

	if err := launcher.Prepare(); err != nil {
		t.Fatalf("Error re-preparing launcher: %s", err)
	}

	// ZBI should be updated if SSH key is regenerated
	shouldChange := []string{launcher.sshKey, launcher.sshPublicKey, launcher.initrd}
	for _, path := range shouldChange {
		if bytes.Equal(getFileHash(t, path), origFileHashes[path]) {
			t.Fatalf("File not updated after SSH key regeneration: %q", path)
		}
	}
}

func TestQemuLauncher(t *testing.T) {
	// Enable subprocess mocking
	ExecCommand = mockCommand
	defer func() { ExecCommand = exec.Command }()

	build, _ := newMockBuild()
	defer os.RemoveAll(build.(*mockBuild).enableQemu(t, FakeQemuNormal))

	launcher := NewQemuLauncher(build)
	if _, err := launcher.Start(); err != nil {
		t.Fatalf("Error starting instance: %s", err)
	}

	alive, err := launcher.IsRunning()
	if err != nil {
		t.Fatalf("Error checking instance status: %s", err)
	}

	if !alive {
		t.Fatalf("instance not alive when it should be")
	}

	var out bytes.Buffer
	if err := launcher.GetLogs(&out); err != nil {
		t.Fatalf("Error getting instance logs: %s", err)
	}
	if diff := cmp.Diff("qemu logs\n", out.String()); diff != "" {
		t.Fatalf("Instance logs missing expected content (-want +got):\n%s", diff)
	}

	if err := launcher.Kill(); err != nil {
		t.Fatalf("Error killing instance: %s", err)
	}

	alive, err = launcher.IsRunning()
	if err != nil {
		t.Fatalf("Error checking instance status: %s", err)
	}

	if alive {
		t.Fatalf("instance alive when it shouldn't be")
	}

	expectPathAbsent(t, launcher.TmpDir)
}
