package rest_websocket

import (
	"context"

	"git.ali33.ru/fcg-xvii/rest"
)

type IApplication interface {
	rest.IApplication
	Incoming() chan<- *WebSocket
	Disconnect() chan<- *WebSocket
}

func NewApplication(ctx context.Context) *Application {
	app := &Application{
		ctx:          ctx,
		chIncoming:   make(chan *WebSocket),
		chDisconnect: make(chan *WebSocket),
	}
	go app.work()
	return app
}

type Application struct {
	sockets      []*WebSocket
	ctx          context.Context
	chIncoming   chan *WebSocket
	chDisconnect chan *WebSocket
}

func (s *Application) Incoming() chan<- *WebSocket {
	return s.chIncoming
}

func (s *Application) Disconnect() chan<- *WebSocket {
	return s.chDisconnect
}

func (s *Application) work() {
	for {
		select {
		case <-s.ctx.Done():
			return
		case socket, ok := <-s.chIncoming:
			if !ok {
				return
			}
			s.addSocket(socket)
		case socket := <-s.chDisconnect:
			for i, sock := range s.sockets {
				if sock == socket {
					s.sockets[i] = nil
					break
				}
			}
		}
	}
}

func (s *Application) searchFree() (int, bool) {
	for i, sock := range s.sockets {
		if sock == nil {
			return i, true
		}
	}
	return -1, false
}

func (s *Application) addSocket(socket *WebSocket) {
	// ищем свободный слот
	index, free := s.searchFree()
	if !free {
		sockets := make([]*WebSocket, len(s.sockets)+50)
		copy(sockets, s.sockets)
		sockets[len(s.sockets)] = socket
	} else {
		s.sockets[index] = socket
	}
}
