// Copyright 2009 The Go 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 signal

import (
	"os"
	"runtime"
	"syscall"
	"testing"
	"time"
)

func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) {
	select {
	case s := <-c:
		if s != sig {
			t.Fatalf("signal was %v, want %v", s, sig)
		}
	case <-time.After(1 * time.Second):
		t.Fatalf("timeout waiting for %v", sig)
	}
}

// Test that basic signal handling works.
func TestSignal(t *testing.T) {
	// Ask for hangup
	c := make(chan os.Signal, 1)
	Notify(c, syscall.Note("hangup"))
	defer Stop(c)

	// Send this process a hangup
	t.Logf("hangup...")
	postNote(syscall.Getpid(), "hangup")
	waitSig(t, c, syscall.Note("hangup"))

	// Ask for everything we can get.
	c1 := make(chan os.Signal, 1)
	Notify(c1)

	// Send this process an alarm
	t.Logf("alarm...")
	postNote(syscall.Getpid(), "alarm")
	waitSig(t, c1, syscall.Note("alarm"))

	// Send two more hangups, to make sure that
	// they get delivered on c1 and that not reading
	// from c does not block everything.
	t.Logf("hangup...")
	postNote(syscall.Getpid(), "hangup")
	waitSig(t, c1, syscall.Note("hangup"))
	t.Logf("hangup...")
	postNote(syscall.Getpid(), "hangup")
	waitSig(t, c1, syscall.Note("hangup"))

	// The first SIGHUP should be waiting for us on c.
	waitSig(t, c, syscall.Note("hangup"))
}

func TestStress(t *testing.T) {
	dur := 3 * time.Second
	if testing.Short() {
		dur = 100 * time.Millisecond
	}
	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
	done := make(chan bool)
	finished := make(chan bool)
	go func() {
		sig := make(chan os.Signal, 1)
		Notify(sig, syscall.Note("alarm"))
		defer Stop(sig)
	Loop:
		for {
			select {
			case <-sig:
			case <-done:
				break Loop
			}
		}
		finished <- true
	}()
	go func() {
	Loop:
		for {
			select {
			case <-done:
				break Loop
			default:
				postNote(syscall.Getpid(), "alarm")
				runtime.Gosched()
			}
		}
		finished <- true
	}()
	time.Sleep(dur)
	close(done)
	<-finished
	<-finished
	// When run with 'go test -cpu=1,2,4' alarm from this test can slip
	// into subsequent TestSignal() causing failure.
	// Sleep for a while to reduce the possibility of the failure.
	time.Sleep(10 * time.Millisecond)
}

// Test that Stop cancels the channel's registrations.
func TestStop(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping in short mode")
	}
	sigs := []string{
		"alarm",
		"hangup",
	}

	for _, sig := range sigs {
		// Send the signal.
		// If it's alarm, we should not see it.
		// If it's hangup, maybe we'll die. Let the flag tell us what to do.
		if sig != "hangup" {
			postNote(syscall.Getpid(), sig)
		}
		time.Sleep(100 * time.Millisecond)

		// Ask for signal
		c := make(chan os.Signal, 1)
		Notify(c, syscall.Note(sig))
		defer Stop(c)

		// Send this process that signal
		postNote(syscall.Getpid(), sig)
		waitSig(t, c, syscall.Note(sig))

		Stop(c)
		select {
		case s := <-c:
			t.Fatalf("unexpected signal %v", s)
		case <-time.After(100 * time.Millisecond):
			// nothing to read - good
		}

		// Send the signal.
		// If it's alarm, we should not see it.
		// If it's hangup, maybe we'll die. Let the flag tell us what to do.
		if sig != "hangup" {
			postNote(syscall.Getpid(), sig)
		}

		select {
		case s := <-c:
			t.Fatalf("unexpected signal %v", s)
		case <-time.After(100 * time.Millisecond):
			// nothing to read - good
		}
	}
}

func itoa(val int) string {
	if val < 0 {
		return "-" + itoa(-val)
	}
	var buf [32]byte // big enough for int64
	i := len(buf) - 1
	for val >= 10 {
		buf[i] = byte(val%10 + '0')
		i--
		val /= 10
	}
	buf[i] = byte(val + '0')
	return string(buf[i:])
}

func postNote(pid int, note string) error {
	f, err := os.OpenFile("/proc/"+itoa(pid)+"/note", os.O_WRONLY, 0)
	if err != nil {
		return err
	}
	defer f.Close()
	_, err = f.Write([]byte(note))
	return err
}
