use strict;
use warnings;
use Future::AsyncAwait;

async sub app {
    my ($scope, $receive, $send) = @_;

    die "Unsupported scope type: $scope->{type}" if $scope->{type} ne 'websocket';

    my $event = await $receive->();
    die "Expected websocket.connect" if $event->{type} ne 'websocket.connect';

    await $send->({ type => 'websocket.accept' });

    while (1) {
        my $frame = await $receive->();
        if ($frame->{type} eq 'websocket.receive') {
            my %payload;
            if (defined $frame->{text}) {
                $payload{text} = "echo: $frame->{text}";
            }
            elsif (defined $frame->{bytes}) {
                $payload{bytes} = $frame->{bytes};
            }
            else {
                next;
            }
            await $send->({ type => 'websocket.send', %payload });
        }
        elsif ($frame->{type} eq 'websocket.disconnect') {
            last;
        }
    }
}

\&app;  # Return coderef when loaded via do
