package syncz

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestWaitGroup_WaitReturnsTrueForZeroCounter(t *testing.T) {
	wg := NewWaitGroup()

	done := wg.Wait(time.Hour)

	assert.True(t, done)
}

func TestWaitGroup_WaitReturnsFalseForZeroTimeout(t *testing.T) {
	wg := NewWaitGroup()

	done := wg.Wait(0)

	assert.False(t, done)
}

func TestWaitGroup_WaitReturnsFalseForNegativeTimeout(t *testing.T) {
	wg := NewWaitGroup()

	done := wg.Wait(-1)

	assert.False(t, done)
}

func TestWaitGroup_WaitReturnsTrueForAddDoneZeroCounter(t *testing.T) {
	wg := NewWaitGroup()
	wg.Add()
	wg.Done()

	done := wg.Wait(time.Hour)

	assert.True(t, done)
}

func TestWaitGroup_WaitReturnsFalseForNonZeroCounter(t *testing.T) {
	wg := NewWaitGroup()
	wg.Add()

	done := wg.Wait(50 * time.Millisecond)

	assert.False(t, done)
}

func TestWaitGroup_WaitReturnsTrueWhenDoneIsCalled(t *testing.T) {
	wg := NewWaitGroup()
	wg.Add()

	go func() {
		time.Sleep(50 * time.Millisecond)
		wg.Done()
	}()

	done := wg.Wait(time.Hour)

	assert.True(t, done)
}

func TestWaitGroup_WaitReturnsFalseWhenNotEnoughDoneIsCalled(t *testing.T) {
	wg := NewWaitGroup()
	wg.Add()
	wg.Add()

	go func() {
		time.Sleep(50 * time.Millisecond)
		wg.Done()
	}()

	done := wg.Wait(200 * time.Millisecond)

	assert.False(t, done)
}

func TestWaitGroup_DoubleDonePanics(t *testing.T) {
	wg := NewWaitGroup()

	assert.PanicsWithValue(t, "Done() called without calling Add()", func() {
		wg.Done()
	})
}
