package utils

import (
	"context"
	"runtime"
	"sync"
)

var glsMap sync.Map

func getGID() int64 {
	var buf [64]byte
	n := runtime.Stack(buf[:], false)
	if n <= 10 { // "goroutine " is 10 bytes
		return 0
	}
	
	// Fast check for prefix "goroutine "
	if buf[0] != 'g' || buf[1] != 'o' || buf[2] != 'r' || buf[3] != 'o' ||
		buf[4] != 'u' || buf[5] != 't' || buf[6] != 'i' || buf[7] != 'n' ||
		buf[8] != 'e' || buf[9] != ' ' {
		return 0
	}

	var id int64
	for i := 10; i < n; i++ {
		c := buf[i]
		if c == ' ' {
			return id
		}
		if c < '0' || c > '9' {
			return 0
		}
		id = id*10 + int64(c-'0')
	}
	return 0
}

// SetContext associates a context with the current goroutine.
func SetContext(ctx context.Context) {
	gid := getGID()
	if gid > 0 {
		glsMap.Store(gid, ctx)
	}
}

// ClearContext removes the context associated with the current goroutine.
func ClearContext() {
	gid := getGID()
	if gid > 0 {
		glsMap.Delete(gid)
	}
}

// GetContext retrieves the context associated with the current goroutine.
func GetContext() context.Context {
	gid := getGID()
	if gid > 0 {
		if val, ok := glsMap.Load(gid); ok {
			if ctx, ok := val.(context.Context); ok {
				return ctx
			}
		}
	}
	return nil
}
