package main

import (
	"fmt"
	"slices"
	"time"
)

// Merge consumes finite, eventually closed inputs. Nil disables an input.
func Merge(a, b <-chan int) []int {
	var out []int
	for a != nil || b != nil {
		select {
		case v, ok := <-a:
			if !ok {
				a = nil
				continue
			}
			out = append(out, v)
		case v, ok := <-b:
			if !ok {
				b = nil
				continue
			}
			out = append(out, v)
		}
	}
	return out
}

func ReceiveWithin(in <-chan int, d time.Duration) (int, bool) {
	timer := time.NewTimer(d)
	defer timer.Stop()
	select {
	case v, ok := <-in:
		return v, ok
	case <-timer.C:
		return 0, false
	}
}

func main() {
	var disabled chan int
	select {
	case disabled <- 1:
		panic("unreachable")
	default:
		fmt.Println("nil channel: default")
	}
	unbuffered := make(chan int)
	select {
	case unbuffered <- 1:
	default:
		fmt.Println("unbuffered: not ready")
	}
	buffered := make(chan int, 1)
	buffered <- 7
	close(buffered)
	a, okA := <-buffered
	b, okB := <-buffered
	fmt.Println(a, okA, b, okB)
	_, ok := ReceiveWithin(nil, time.Millisecond)
	fmt.Println("nil receive timed out:", !ok)
	aIn, bIn := make(chan int, 2), make(chan int, 2)
	aIn <- 1
	aIn <- 3
	bIn <- 2
	bIn <- 4
	close(aIn)
	close(bIn)
	merged := Merge(aIn, bIn)
	slices.Sort(merged)
	fmt.Println("merged, sorted:", merged)
}
