package stack

import (
	"context"
	"sync"
	"time"
)

var (
	EarlyDialogs = NewDialogManager[*StreamWaiting]()
)

type StreamWaiting struct {
	onPublishCb chan int // 等待推流hook的管道
	cancelFunc  func()   // 取消等待推流hook的ctx
	Data        interface{}
}

func (s *StreamWaiting) Receive(seconds int) int {
	s.onPublishCb = make(chan int, 0)
	timeout, cancelFunc := context.WithTimeout(context.Background(), time.Duration(seconds)*time.Second)
	s.cancelFunc = cancelFunc
	select {
	case code := <-s.onPublishCb:
		return code
	case <-timeout.Done():
		s.cancelFunc = nil
		return -1
	}
}
func (s *StreamWaiting) Put(code int) {
	s.onPublishCb <- code
}

type DialogManager[T any] struct {
	lock    sync.RWMutex
	dialogs map[string]T
}

func (d *DialogManager[T]) Add(id string, dialog T) (T, bool) {
	d.lock.Lock()
	defer d.lock.Unlock()

	var old T
	var ok bool
	if old, ok = d.dialogs[id]; ok {
		return old, false
	}

	d.dialogs[id] = dialog
	return old, true
}

func (d *DialogManager[T]) Find(id string) T {
	d.lock.RLock()
	defer d.lock.RUnlock()
	return d.dialogs[id]
}

func (d *DialogManager[T]) Remove(id string) T {
	d.lock.Lock()
	defer d.lock.Unlock()
	dialog := d.dialogs[id]
	delete(d.dialogs, id)
	return dialog
}

func NewDialogManager[T any]() *DialogManager[T] {
	return &DialogManager[T]{
		dialogs: make(map[string]T),
	}
}
