#!/usr/bin/env perl
# 20260219 ChatGPT
# $Id$
# $HeadURL$

use strict;
use warnings;

use Mojolicious::Lite -signatures;
use Mojo::IOLoop;
use IO::Socket::INET;

my $udp_port = 1777;

# Track websocket clients
my %clients;

websocket '/stream' => sub ($c) {
  my $id = sprintf("%x", rand(0xffffffff));
  $clients{$id} = $c->tx;

  $c->on(finish => sub ($c, $code, $reason) {
    delete $clients{$id};
  });
};

# UDP socket (non-blocking)
my $udp = IO::Socket::INET->new(
  LocalPort => $udp_port,
  Proto     => 'udp',
) or die "udp bind $udp_port: $!\n";

$udp->blocking(0);

# Register UDP fd with Mojo reactor
my $loop = Mojo::IOLoop->singleton;

#Mojo::IOLoop->reactor->io($udp => sub ($reactor, $writable) {
$loop->reactor->io($udp => sub ($reactor, $writable) {
  my $datagram = '';
  my $peer = $udp->recv($datagram, 2048);
  return unless defined $peer && length $datagram;

  $datagram =~ s/\r?\n$//;

  for my $id (keys %clients) {
    my $tx = $clients{$id};
    next unless $tx && !$tx->is_finished;
    $tx->send($datagram);
  }
});

#Mojo::IOLoop->reactor->watch($udp, 1, 0);
$loop->reactor->watch($udp, 1, 0);

get '/' => sub ($c) {
  $c->render(text => "udp2ws up (udp:$udp_port ws:/stream)\n");
};

app->start;
