// Package shutdown provides graceful shutdown handling for services.
package shutdown

import (
	"context"
	"os"
	"os/signal"
	"syscall"
)

// Hook is a cleanup function called during shutdown.
type Hook struct {
	Name string
	Fn   func() error
}

// simpleLogger is the minimal interface required from a logger.
type simpleLogger interface {
	Info(string)
	Error(string, error)
}

// Handle blocks until SIGTERM or SIGINT is received, then cancels the context
// and runs hooks in order. Each hook error is logged but does not abort remaining hooks.
func Handle(ctx context.Context, cancel context.CancelFunc, hooks []Hook, logger simpleLogger) {
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGTERM, syscall.SIGINT)
	defer signal.Stop(quit)

	select {
	case sig := <-quit:
		logger.Info("shutdown signal received: " + sig.String())
	case <-ctx.Done():
		logger.Info("context cancelled, shutting down")
	}

	cancel()

	for _, h := range hooks {
		logger.Info("running shutdown hook: " + h.Name)
		if err := h.Fn(); err != nil {
			logger.Error("shutdown hook "+h.Name+" failed", err)
		}
	}
}
