// 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"
)

const leakWaitTime = 250 * time.Millisecond

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, leakWaitTime)()
	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))
	}
}

func TestFormat(t *testing.T) {
	defer NoLeaks(t, leakWaitTime)()

	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, false)
	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, leakWaitTime)

	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)
	}
}
