package media_test

import (
	"context"
	"sync"
	"testing"
	"time"

	"git.netflux.io/rob/clipper/media"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"go.uber.org/zap"
)

func TestWorkerPool(t *testing.T) {
	ctx := context.Background()

	p := media.NewWorkerPool(2, 1, zap.NewNop().Sugar())
	p.Run()

	const taskCount = 4
	const dur = time.Millisecond * 100

	ch := make(chan error, taskCount)
	var wg sync.WaitGroup
	wg.Add(taskCount)

	for i := 0; i < taskCount; i++ {
		go func() {
			defer wg.Done()
			ch <- p.WaitForTask(ctx, func() error { time.Sleep(dur); return nil })
		}()
	}

	wg.Wait()
	close(ch)

	var okCount, errCount int

	for err := range ch {
		if err == nil {
			okCount++
		} else {
			errCount++
			require.EqualError(t, err, "worker queue full")
		}
	}

	// There can either be 1 or 2 failures, depending on whether a worker picks
	// up one job before the last one is added to the queue.
	ok := (okCount == 2 && errCount == 2) || (okCount == 3 && errCount == 1)
	assert.True(t, ok)
}
