package common

import "context"

// threadsafe
type TaskQueue[T any] struct {
	Queue[*T]
	maxsize int
	hasNew     chan struct{}
}

func NewTaskQueue[T any](maxsize int, threadsafe bool) *TaskQueue[T] {
	return &TaskQueue[T]{
		Queue  : *NewQueue[*T](threadsafe),
		maxsize: maxsize,
		hasNew : make(chan struct{}, 1),
	}
}

func (q *TaskQueue[T]) Push(t *T) (ok bool) {
	if q.Len() >= q.maxsize {
		return false
	} else {
		q.In(t)
		select {
			case q.hasNew <- struct{}{}:
			default: 
		}
		return true
	}
}

func (q *TaskQueue[T]) Pop() *T {
	return q.Out()
}

func (q *TaskQueue[T]) WaitForNew(ctx context.Context) *T {
	for {
		t := q.Out()
		if t != nil {
			return t
		}
		select {
			case <-ctx.Done(): return nil
			case <-q.hasNew:
		}
	}
}
