package vault

import (
	"context"
	"path/filepath"
	"strings"
	"sync"
)

type memoryPathLock struct {
	token chan struct{}
}

var memoryPathLocks sync.Map // map[string]*memoryPathLock

func lockMemoryPath(ctx context.Context, targetPath string) (func(), error) {
	key := filepath.Clean(strings.TrimSpace(targetPath))
	if key == "." || key == "" {
		key = strings.TrimSpace(targetPath)
	}
	value, ok := memoryPathLocks.Load(key)
	if !ok {
		lock := &memoryPathLock{token: make(chan struct{}, 1)}
		lock.token <- struct{}{}
		value, _ = memoryPathLocks.LoadOrStore(key, lock)
	}
	lock := value.(*memoryPathLock)
	if ctx == nil {
		ctx = context.Background()
	}
	if err := ctx.Err(); err != nil {
		return nil, err
	}
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	case <-lock.token:
		return func() { lock.token <- struct{}{} }, nil
	}
}
