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

import (
	"bytes"
	"runtime"
	"strings"
	"sync"
	"testing"
	"time"
)

func wrappedWaitForIt(wg *sync.WaitGroup, wait chan struct{}, n int64) {
	if n == 0 {
		waitForIt(wg, wait)
	} else {
		wrappedWaitForIt(wg, wait, n-1)
	}
}

func waitForIt(wg *sync.WaitGroup, wait chan struct{}) {
	wg.Done()
	<-wait
}

func runGoA(wg *sync.WaitGroup, wait chan struct{}) {
	go waitForIt(wg, wait)
}

func runGoB(wg *sync.WaitGroup, wait chan struct{}) {
	go wrappedWaitForIt(wg, wait, 3)
}

func runGoC(wg *sync.WaitGroup, wait chan struct{}) {
	go func() {
		wg.Done()
		<-wait
	}()
}

func TestGet(t *testing.T) {
	defer NoLeaks(t, 100*time.Millisecond)()
	var wg sync.WaitGroup
	wg.Add(3)
	wait := make(chan struct{})
	runGoA(&wg, wait)
	runGoB(&wg, wait)
	runGoC(&wg, wait)
	wg.Wait()
	gs, err := Get()
	if err != nil {
		t.Fatal(err)
	}
	close(wait)

	if len(gs) < 4 {
		t.Errorf("Got %d goroutines, expected at least 4", len(gs))
	}
	bycreator := map[string]*Goroutine{}
	for _, g := range gs {
		key := ""
		if g.Creator != nil {
			key = g.Creator.Call
		}
		bycreator[key] = g
	}
	a := bycreator["v.io/x/ref/test/goroutines.runGoA"]
	if a == nil {
		t.Errorf("runGoA is missing")
	} else if len(a.Stack) < 1 {
		t.Errorf("got %d expected at least 1: %s", len(a.Stack), Format(a))
	} else if !strings.HasPrefix(a.Stack[0].Call, "v.io/x/ref/test/goroutines.waitForIt") {
		t.Errorf("got %s, wanted it to start with v.io/x/ref/test/goroutines.waitForIt",
			a.Stack[0].Call)
	}
	b := bycreator["v.io/x/ref/test/goroutines.runGoB"]
	if b == nil {
		t.Errorf("runGoB is missing")
	} else if len(b.Stack) < 5 {
		t.Errorf("got %d expected at least 5: %s", len(b.Stack), Format(b))
	}
	c := bycreator["v.io/x/ref/test/goroutines.runGoC"]
	if c == nil {
		t.Errorf("runGoC is missing")
	} else if len(c.Stack) < 1 {
		t.Errorf("got %d expected at least 1: %s", len(c.Stack), Format(c))
	} else if !strings.HasPrefix(c.Stack[0].Call, "v.io/x/ref/test/goroutines.") {
		t.Errorf("got %s, wanted it to start with v.io/x/ref/test/goroutines.",
			c.Stack[0].Call)
	}
}

func TestFormat(t *testing.T) {
	defer NoLeaks(t, 100*time.Millisecond)()

	var wg sync.WaitGroup
	wg.Add(3)
	wait := make(chan struct{})
	runGoA(&wg, wait)
	runGoB(&wg, wait)
	runGoC(&wg, wait)
	wg.Wait()

	buf := make([]byte, 1<<20)
	buf = buf[:runtime.Stack(buf, true)]
	close(wait)

	gs, err := Parse(buf)
	if err != nil {
		t.Fatal(err)
	}
	if formatted := Format(gs...); !bytes.Equal(buf, formatted) {
		t.Errorf("got:\n%s\nwanted:\n%s\n", string(formatted), string(buf))
	}
}

type fakeErrorReporter struct {
	calls     int
	extra     int
	formatted string
}

func (f *fakeErrorReporter) Errorf(format string, args ...interface{}) {
	f.calls++
	f.extra = args[0].(int)
	f.formatted = args[1].(string)
}

func TestNoLeaks(t *testing.T) {
	er := &fakeErrorReporter{}
	f := NoLeaks(er, 100*time.Millisecond)

	var wg sync.WaitGroup
	wg.Add(3)
	wait := make(chan struct{})
	runGoA(&wg, wait)
	runGoB(&wg, wait)
	runGoC(&wg, wait)
	wg.Wait()

	f()
	if er.calls != 1 {
		t.Errorf("got %d, wanted 1: %s", er.calls, er.formatted)
	}
	if er.extra != 3 {
		t.Errorf("got %d, wanted 3: %s", er.extra, er.formatted)
	}
	close(wait)

	*er = fakeErrorReporter{}
	f()
	if er.calls != 0 {
		t.Errorf("got %d, wanted 0: %s", er.calls, er.formatted)
	}
	if er.extra != 0 {
		t.Errorf("got %d, wanted 0: %s", er.extra, er.formatted)
	}
}
