// Package scheduler provides a modular registry for MP-QUIC path schedulers.
//
// Adding a new scheduler:
//  1. Create a new file in this package (e.g., myscheduler.go)
//  2. Implement quic.PathScheduler (SelectPath, UpdateQuota, Reset)
//  3. In an init() function, call Register("myscheduler", factory)
//
// See custom_example.go for a complete example.
package scheduler

import (
	"fmt"
	"sort"
	"sync"

	quic "github.com/AeonDave/mp-quic-go"
)

// Factory is a function that creates a new PathScheduler instance.
type Factory func() quic.PathScheduler

var (
	mu        sync.RWMutex
	factories = make(map[string]Factory)
)

// Register adds a scheduler factory to the registry.
// Call this from init() in each scheduler file.
func Register(name string, factory Factory) {
	mu.Lock()
	defer mu.Unlock()
	if _, exists := factories[name]; exists {
		panic(fmt.Sprintf("scheduler: duplicate registration for %q", name))
	}
	factories[name] = factory
}

// Get creates a new instance of the named scheduler.
// Returns an error if the name is not registered.
func Get(name string) (quic.PathScheduler, error) {
	mu.RLock()
	defer mu.RUnlock()
	factory, exists := factories[name]
	if !exists {
		return nil, fmt.Errorf("scheduler: unknown scheduler %q (available: %v)", name, List())
	}
	return factory(), nil
}

// List returns sorted names of all registered schedulers.
func List() []string {
	mu.RLock()
	defer mu.RUnlock()
	names := make([]string, 0, len(factories))
	for name := range factories {
		names = append(names, name)
	}
	sort.Strings(names)
	return names
}
