package main

import (
	"context"
	"log"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"
)

// section: code

func main() {
	// Create signal-aware context at application root
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()

	log.Println("Starting application with 3 workers")
	log.Println("Press Ctrl+C to trigger graceful shutdown")

	var wg sync.WaitGroup

	// Start multiple workers that all observe the same context
	for i := 1; i <= 3; i++ {
		wg.Add(1)
		go worker(ctx, &wg, i)
	}

	// Wait for all workers to complete
	wg.Wait()
	log.Println("All workers stopped, application exiting")
}

func worker(ctx context.Context, wg *sync.WaitGroup, id int) {
	defer wg.Done()

	log.Printf("Worker %d: Started", id)

	ticker := time.NewTicker(1 * time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-ctx.Done():
			// Context canceled due to signal
			log.Printf("Worker %d: Received shutdown signal, cleaning up...", id)

			// Simulate cleanup work
			time.Sleep(500 * time.Millisecond)

			log.Printf("Worker %d: Stopped", id)
			return

		case t := <-ticker.C:
			// Normal work
			log.Printf("Worker %d: Working at %s", id, t.Format("15:04:05"))
		}
	}
}

// section: output
/*
2025/01/15 10:30:00 Starting application with 3 workers
2025/01/15 10:30:00 Press Ctrl+C to trigger graceful shutdown
2025/01/15 10:30:00 Worker 1: Started
2025/01/15 10:30:00 Worker 2: Started
2025/01/15 10:30:00 Worker 3: Started
2025/01/15 10:30:01 Worker 1: Working at 10:30:01
2025/01/15 10:30:01 Worker 2: Working at 10:30:01
2025/01/15 10:30:01 Worker 3: Working at 10:30:01
2025/01/15 10:30:02 Worker 1: Working at 10:30:02
2025/01/15 10:30:02 Worker 2: Working at 10:30:02
2025/01/15 10:30:02 Worker 3: Working at 10:30:02
^C
2025/01/15 10:30:03 Worker 2: Received shutdown signal, cleaning up...
2025/01/15 10:30:03 Worker 1: Received shutdown signal, cleaning up...
2025/01/15 10:30:03 Worker 3: Received shutdown signal, cleaning up...
2025/01/15 10:30:03 Worker 2: Stopped
2025/01/15 10:30:03 Worker 1: Stopped
2025/01/15 10:30:03 Worker 3: Stopped
2025/01/15 10:30:03 All workers stopped, application exiting
*/
