// Copyright 2015 The Vanadium 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 rt_test

import (
	"fmt"
	"io"
	"os"
	"syscall"
	"testing"

	"v.io/v23"
	"v.io/x/ref/lib/signals"
	"v.io/x/ref/test/modules"
)

//go:generate v23 test generate

var cstderr io.Writer

func init() {
	if testing.Verbose() {
		cstderr = os.Stderr
	}
}

func newShell(t *testing.T) *modules.Shell {
	sh, err := modules.NewShell(nil, nil, testing.Verbose(), t)
	if err != nil {
		t.Fatalf("unexpected error: %s", err)
	}
	return sh
}

// TestSimpleServerSignal verifies that sending a signal to the simple server
// causes it to exit cleanly.
func TestSimpleServerSignal(t *testing.T) {
	sh := newShell(t)
	defer sh.Cleanup(os.Stdout, cstderr)
	h, _ := sh.Start(nil, simpleServerProgram)
	h.Expect("Ready")
	syscall.Kill(h.Pid(), syscall.SIGINT)
	h.Expect("Received signal interrupt")
	h.Expect("Interruptible cleanup")
	h.Expect("Deferred cleanup")
	fmt.Fprintln(h.Stdin(), "close")
	h.ExpectEOF()
}

// TestSimpleServerLocalStop verifies that sending a local stop command to the
// simple server causes it to exit cleanly.
func TestSimpleServerLocalStop(t *testing.T) {
	sh := newShell(t)
	defer sh.Cleanup(os.Stdout, cstderr)
	h, _ := sh.Start(nil, simpleServerProgram)
	h.Expect("Ready")
	fmt.Fprintln(h.Stdin(), "stop")
	h.Expect(fmt.Sprintf("Received signal %s", v23.LocalStop))
	h.Expect("Interruptible cleanup")
	h.Expect("Deferred cleanup")
	fmt.Fprintln(h.Stdin(), "close")
	h.ExpectEOF()
}

// TestSimpleServerDoubleSignal verifies that sending a succession of two
// signals to the simple server causes it to initiate the cleanup sequence on
// the first signal and then exit immediately on the second signal.
func TestSimpleServerDoubleSignal(t *testing.T) {
	sh := newShell(t)
	defer sh.Cleanup(os.Stdout, cstderr)
	h, _ := sh.Start(nil, simpleServerProgram)
	h.Expect("Ready")
	syscall.Kill(h.Pid(), syscall.SIGINT)
	h.Expect("Received signal interrupt")
	syscall.Kill(h.Pid(), syscall.SIGINT)
	err := h.Shutdown(os.Stdout, cstderr)
	if err == nil {
		t.Fatalf("expected an error")
	}
	if got, want := err.Error(), fmt.Sprintf("exit status %d", signals.DoubleStopExitCode); got != want {
		t.Errorf("got %q, want %q", got, want)
	}
}

// TestSimpleServerLocalForceStop verifies that sending a local ForceStop
// command to the simple server causes it to exit immediately.
func TestSimpleServerLocalForceStop(t *testing.T) {
	sh := newShell(t)
	defer sh.Cleanup(os.Stdout, cstderr)
	h, _ := sh.Start(nil, simpleServerProgram)
	h.Expect("Ready")
	fmt.Fprintln(h.Stdin(), "forcestop")
	h.Expect("straight exit")
	err := h.Shutdown(os.Stdout, cstderr)
	if err == nil {
		t.Fatalf("expected an error")
	}
	if got, want := err.Error(), fmt.Sprintf("exit status %d", v23.ForceStopExitCode); got != want {
		t.Errorf("got %q, want %q", got, want)
	}
}

// TestSimpleServerKill demonstrates that a SIGKILL still forces the server
// to exit regardless of our signal handling.
func TestSimpleServerKill(t *testing.T) {
	sh := newShell(t)
	defer sh.Cleanup(os.Stdout, cstderr)
	h, _ := sh.Start(nil, simpleServerProgram)
	h.Expect("Ready")
	syscall.Kill(h.Pid(), syscall.SIGKILL)
	err := h.Shutdown(os.Stdout, cstderr)
	if err == nil {
		t.Fatalf("expected an error")
	}
	if got, want := err.Error(), "signal: killed"; got != want {
		t.Errorf("got %q, want %q", got, want)
	}
}

// TestComplexServerSignal verifies that sending a signal to the complex server
// initiates the cleanup sequence in that server (we observe the printouts
// corresponding to all the simulated sequential/parallel and
// blocking/interruptible shutdown steps), and then exits cleanly.
func TestComplexServerSignal(t *testing.T) {
	sh := newShell(t)
	defer sh.Cleanup(os.Stdout, cstderr)
	h, _ := sh.Start(nil, complexServerProgram)
	h.Expect("Ready")
	syscall.Kill(h.Pid(), syscall.SIGINT)
	h.Expect("Received signal interrupt")
	h.ExpectSetRE("Sequential blocking cleanup",
		"Sequential interruptible cleanup",
		"Parallel blocking cleanup1",
		"Parallel blocking cleanup2",
		"Parallel interruptible cleanup1",
		"Parallel interruptible cleanup2")
	fmt.Fprintln(h.Stdin(), "close")
	h.ExpectEOF()
}

// TestComplexServerLocalStop verifies that sending a local stop command to the
// complex server initiates the cleanup sequence in that server (we observe the
// printouts corresponding to all the simulated sequential/parallel and
// blocking/interruptible shutdown steps), and then exits cleanly.
func TestComplexServerLocalStop(t *testing.T) {
	sh := newShell(t)
	defer sh.Cleanup(os.Stdout, cstderr)
	h, _ := sh.Start(nil, complexServerProgram)
	h.Expect("Ready")

	fmt.Fprintln(h.Stdin(), "stop")
	h.Expect(fmt.Sprintf("Stop %s", v23.LocalStop))
	h.ExpectSetRE(
		"Sequential blocking cleanup",
		"Sequential interruptible cleanup",
		"Parallel blocking cleanup1",
		"Parallel blocking cleanup2",
		"Parallel interruptible cleanup1",
		"Parallel interruptible cleanup2",
	)
	fmt.Fprintln(h.Stdin(), "close")
	h.ExpectEOF()
}

// TestComplexServerDoubleSignal verifies that sending a succession of two
// signals to the complex server has the expected effect: the first signal
// initiates the cleanup steps and the second signal kills the process, but only
// after the blocking shutdown steps were allowed to complete (as observed by
// the corresponding printouts from the server).  Note that we have no
// expectations on whether or not the interruptible shutdown steps execute.
func TestComplexServerDoubleSignal(t *testing.T) {
	sh := newShell(t)
	defer sh.Cleanup(os.Stdout, cstderr)
	h, _ := sh.Start(nil, complexServerProgram)
	h.Expect("Ready")
	syscall.Kill(h.Pid(), syscall.SIGINT)
	h.Expect("Received signal interrupt")
	syscall.Kill(h.Pid(), syscall.SIGINT)
	h.ExpectSetEventuallyRE(
		"Sequential blocking cleanup",
		"Parallel blocking cleanup1",
		"Parallel blocking cleanup2")
	err := h.Shutdown(os.Stdout, cstderr)
	if err == nil {
		t.Fatalf("expected an error")
	}
	if got, want := err.Error(), fmt.Sprintf("exit status %d", signals.DoubleStopExitCode); got != want {
		t.Errorf("got %q, want %q", got, want)
	}
}

// TestComplexServerLocalForceStop verifies that sending a local ForceStop
// command to the complex server forces it to exit immediately.
func TestComplexServerLocalForceStop(t *testing.T) {
	sh := newShell(t)
	defer sh.Cleanup(os.Stdout, cstderr)
	h, _ := sh.Start(nil, complexServerProgram)
	h.Expect("Ready")
	fmt.Fprintln(h.Stdin(), "forcestop")
	h.Expect("straight exit")
	err := h.Shutdown(os.Stdout, cstderr)
	if err == nil {
		t.Fatalf("expected an error")
	}
	if got, want := err.Error(), fmt.Sprintf("exit status %d", v23.ForceStopExitCode); got != want {
		t.Errorf("got %q, want %q", got, want)
	}
}

// TestComplexServerKill demonstrates that a SIGKILL still forces the server to
// exit regardless of our signal handling.
func TestComplexServerKill(t *testing.T) {
	sh := newShell(t)
	defer sh.Cleanup(os.Stdout, cstderr)
	h, _ := sh.Start(nil, complexServerProgram)
	h.Expect("Ready")
	syscall.Kill(h.Pid(), syscall.SIGKILL)
	err := h.Shutdown(os.Stdout, cstderr)
	if err == nil {
		t.Fatalf("expected an error")
	}
	if got, want := err.Error(), "signal: killed"; got != want {
		t.Errorf("got %q, want %q", got, want)
	}
}
