// Copyright Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// leak checks for goroutine leaks in tests
// This is (heavily) inspired by https://github.com/grpc/grpc-go/blob/master/internal/leakcheck/leakcheck.go
// and https://github.com/fortytw2/leaktest
package leak

import (
	"errors"
	"fmt"
	"os"
	"runtime"
	"sort"
	"strconv"
	"strings"
	"time"
)

import (
	"go.uber.org/atomic"
	"istio.io/pkg/log"
)

import (
	"github.com/apache/dubbo-go-pixiu/pkg/test"
	"github.com/apache/dubbo-go-pixiu/pkg/test/util/retry"
)

var goroutinesToIgnore = []string{
	// "global" goroutines we always initialize. Maybe we shouldn't always initialize these, but for now every
	// test fails with these
	"k8s.io/klog/v2.(*loggingT).flushDaemon",      // k8s logging
	"go.opencensus.io/stats/view.(*worker).start", // metrics runs on init. Maybe it should be in main()

	// goroutines for test
	"testing.Main(",
	"testing.tRunner(",
	"testing.(*M).",

	// go runtime
	"runtime.goexit",
	"created by runtime.gc",
	"runtime.MHeap_Scavenger",
	"signal.signal_recv",
	"sigterm.handler",
	"runtime_mcall",

	// created by leak checker
	"created by runtime/trace.Start",
	"interestingGoroutines",

	// This is not technically required. However, its a loop that is outside our control that runs every 500ms
	// so we skip it to avoid delayed tests
	"workqueue.(*Type).updateUnfinishedWorkLoop",
}

// TestingM is the minimal subset of testing.M that we use.
type TestingM interface {
	Run() int
}

type TestingTB interface {
	Cleanup(func())
	Errorf(format string, args ...interface{})
}

var gracePeriod = time.Second * 5

func check(filter func(in []*goroutine) []*goroutine) error {
	// Loop, waiting for goroutines to shut down.
	// Wait up to timeout, but finish as quickly as possible.
	// The timeout here is not super sensitive, since if we hit this we will fail; a happy case will finish quickly
	deadline := time.Now().Add(gracePeriod)
	var leaked []*goroutine
	var err error
	delay := time.Duration(0)
	for time.Now().Before(deadline) {
		leaked, err = interestingGoroutines()
		if err != nil {
			return fmt.Errorf("failed to fetch post-test goroutines: %v", err)
		}
		if filter != nil {
			leaked = filter(leaked)
		}
		if len(leaked) == 0 {
			return nil
		}
		time.Sleep(delay)
		delay += time.Millisecond * 10
	}
	errString := strings.Builder{}
	for _, g := range leaked {
		errString.WriteString(fmt.Sprintf("Leaked goroutine: %v\n", g.stack))
	}
	return errors.New(errString.String())
}

// Check adds a check to a test to ensure there are no leaked goroutines
// To use, simply call leak.Check(t) at the start of a test; Do not call it in defer.
// It is recommended to call this as the first step, as Cleanup is called in LIFO order; this ensures any
// Cleanup's called in the test happen first.
// Any existing goroutines before the test starts are filtered out. This ensures a single test failing doesn't
// cause all future tests to fail. However, it is still possible another test influences the result when t.Parallel is used.
// Where possible, CheckMain is preferred.
func Check(t TestingTB) {
	existingRaw, err := interestingGoroutines()
	if err != nil {
		t.Errorf("failed to fetch pre-test goroutines: %v", err)
		return
	}
	existing := map[uint64]struct{}{}
	for _, g := range existingRaw {
		existing[g.id] = struct{}{}
	}
	filter := func(in []*goroutine) []*goroutine {
		res := make([]*goroutine, 0, len(in))
		for _, i := range in {
			if _, f := existing[i.id]; !f {
				// This was not in the goroutines list when the test started
				res = append(res, i)
			}
		}
		return res
	}
	t.Cleanup(func() {
		if err := check(filter); err != nil {
			t.Errorf("goroutine leak: %v", err)
		}
	})
}

// CheckMain asserts that no goroutines are leaked after a test package exits.
// This can be used with the following code:
//
//	func TestMain(m *testing.M) {
//	    leak.CheckMain(m)
//	}
//
// Failures here are scoped to the package, not a specific test. To determine the source of the failure,
// you can use the tool `go test -exec $PWD/tools/go-ordered-test ./my/package`. This runs each test individually.
// If there are some tests that are leaky, you the Check method can be used on individual tests.
func CheckMain(m TestingM) {
	exitCode := m.Run()

	if exitCode == 0 {
		if err := check(nil); err != nil {
			log.Errorf("fatal: %v", err)
			exitCode = 1
		}
	}

	os.Exit(exitCode)
}

// MustGarbageCollect asserts than an object was garbage collected by the end of the test.
// The input must be a pointer to an object.
func MustGarbageCollect(tb test.Failer, i interface{}) {
	tb.Helper()
	collected := atomic.NewBool(false)
	runtime.SetFinalizer(i, func(x interface{}) {
		collected.Store(true)
	})
	tb.Cleanup(func() {
		retry.UntilOrFail(tb, func() bool {
			// Trigger GC explicitly, otherwise we may need to wait a long time for it to run
			runtime.GC()
			return collected.Load()
		}, retry.Timeout(time.Second*5), retry.Message("object was not garbage collected"))
	})
}

type goroutine struct {
	id    uint64
	stack string
}

type goroutineByID []*goroutine

func (g goroutineByID) Len() int           { return len(g) }
func (g goroutineByID) Less(i, j int) bool { return g[i].id < g[j].id }
func (g goroutineByID) Swap(i, j int)      { g[i], g[j] = g[j], g[i] }

func interestingGoroutine(g string) (*goroutine, error) {
	sl := strings.SplitN(g, "\n", 2)
	if len(sl) != 2 {
		return nil, fmt.Errorf("error parsing stack: %q", g)
	}
	stack := strings.TrimSpace(sl[1])
	if strings.HasPrefix(stack, "testing.RunTests") {
		return nil, nil
	}

	for _, s := range goroutinesToIgnore {
		if strings.Contains(stack, s) {
			return nil, nil
		}
	}

	// Parse the goroutine's ID from the header line.
	h := strings.SplitN(sl[0], " ", 3)
	if len(h) < 3 {
		return nil, fmt.Errorf("error parsing stack header: %q", sl[0])
	}
	id, err := strconv.ParseUint(h[1], 10, 64)
	if err != nil {
		return nil, fmt.Errorf("error parsing goroutine id: %s", err)
	}

	return &goroutine{id: id, stack: strings.TrimSpace(g)}, nil
}

// interestingGoroutines returns all goroutines we care about for the purpose
// of leak checking. It excludes testing or runtime ones.
func interestingGoroutines() ([]*goroutine, error) {
	buf := make([]byte, 2<<20)
	buf = buf[:runtime.Stack(buf, true)]
	var gs []*goroutine
	for _, g := range strings.Split(string(buf), "\n\n") {
		gr, err := interestingGoroutine(g)
		if err != nil {
			return nil, err
		} else if gr == nil {
			continue
		}
		gs = append(gs, gr)
	}
	sort.Sort(goroutineByID(gs))
	return gs, nil
}
