// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package chans

import (
	"context"
	"runtime"
	"sort"
	"sync"
	"testing"
	"time"

	"slices"
)

func TestReadAll(t *testing.T) {
	c := make(chan int)
	go func() {
		c <- 4
		c <- 2
		c <- 5
		close(c)
	}()
	got := ReadAll(context.Background(), c)
	want := []int{4, 2, 5}
	if !slices.Equal(got, want) {
		t.Errorf("ReadAll returned %v, want %v", got, want)
	}
}

func TestMerge(t *testing.T) {
	c1 := make(chan int)
	c2 := make(chan int)
	go func() {
		c1 <- 1
		c1 <- 3
		c1 <- 5
		close(c1)
	}()
	go func() {
		c2 <- 2
		c2 <- 4
		c2 <- 6
		close(c2)
	}()
	ctx := context.Background()
	got := ReadAll(ctx, Merge(ctx, c1, c2))
	sort.Ints(got)
	want := []int{1, 2, 3, 4, 5, 6}
	if !slices.Equal(got, want) {
		t.Errorf("Merge returned %v, want %v", got, want)
	}
}

func TestFilter(t *testing.T) {
	c := make(chan int)
	go func() {
		c <- 1
		c <- 2
		c <- 3
		close(c)
	}()
	even := func(i int) bool { return i%2 == 0 }
	ctx := context.Background()
	got := ReadAll(ctx, Filter(ctx, c, even))
	want := []int{2}
	if !slices.Equal(got, want) {
		t.Errorf("Filter returned %v, want %v", got, want)
	}
}

func TestSink(t *testing.T) {
	c := Sink[int](context.Background())
	after := time.NewTimer(time.Minute)
	defer after.Stop()
	send := func(v int) {
		select {
		case c <- v:
		case <-after.C:
			t.Error("timed out sending to Sink")
		}
	}
	send(1)
	send(2)
	send(3)
	close(c)
}

func TestExclusive(t *testing.T) {
	val := 0
	ex := MakeExclusive(&val)

	var wg sync.WaitGroup
	f := func() {
		defer wg.Done()
		for i := 0; i < 10; i++ {
			p := ex.Acquire()
			(*p)++
			ex.Release(p)
		}
	}

	wg.Add(2)
	go f()
	go f()

	wg.Wait()
	if val != 20 {
		t.Errorf("after Acquire/Release loop got %d, want 20", val)
	}
}

func TestExclusiveTry(t *testing.T) {
	s := ""
	ex := MakeExclusive(&s)
	p, ok := ex.TryAcquire()
	if !ok {
		t.Fatalf("TryAcquire failed")
	}
	*p = "a"

	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		defer wg.Done()
		_, ok := ex.TryAcquire()
		if ok {
			t.Errorf("TryAcquire succeeded unexpectedly")
		}
	}()
	wg.Wait()

	ex.Release(p)

	p, ok = ex.TryAcquire()
	if !ok {
		t.Errorf("TryAcquire failed")
	}
}

func TestRanger(t *testing.T) {
	s, r := Ranger[int]()

	ctx := context.Background()
	go func() {
		// Receive one value then exit.
		v, ok := r.Next(ctx)
		if !ok {
			t.Errorf("did not receive any values")
		} else if v != 1 {
			t.Errorf("received %d, want 1", v)
		}
	}()

	c1 := make(chan bool)
	c2 := make(chan bool)
	go func() {
		defer close(c2)
		if !s.Send(ctx, 1) {
			t.Errorf("Send failed unexpectedly")
		}
		close(c1)
		if s.Send(ctx, 2) {
			t.Errorf("Send succeeded unexpectedly")
		}
	}()

	<-c1

	// Force a garbage collection to try to get the finalizers to run.
	runtime.GC()

	select {
	case <-c2:
	case <-time.After(time.Minute):
		t.Error("Ranger Send should have failed, but timed out")
	}
}
