use lib 'lib';
use lib 'specs/support';
use BDD::Behave;
use BloginTest;
use Blogin::Server;
use Cro::HTTP::Server;
use Cro::WebSocket::Client;
use JSON::Fast;

constant PORT = 31789;

sub with-socket(&body) {
  my $out    = temp-made('reload-socket');
  my $reload = Blogin::Server::ReloadChannel.new;

  my $server = Cro::HTTP::Server.new(
    host        => 'localhost',
    port        => PORT,
    application => Blogin::Server::make-app($out, reload => $reload),
  );

  $server.start;

  my $connection = await Cro::WebSocket::Client.new(uri => "ws://localhost:{ PORT }/__blogin-reload").connect;
  my $messages   = Channel.new;
  my $tap        = $connection.messages.tap(-> $message { $messages.send(from-json(await $message.body-text)) });

  LEAVE {
    $tap.close;
    await $connection.close;
    $server.stop;
    nuke($out);
  }

  body($reload, $messages);
}

describe 'a page connected to the reload socket', {
  it 'is greeted with the build version it should be showing', {
    with-socket(-> $reload, $messages {
      expect($messages.receive<version>).to.eq(0);
    });
  }

  it 'is greeted with the session of the running server', {
    with-socket(-> $reload, $messages {
      expect($messages.receive<session>).to.eq($reload.session);
    });
  }

  it 'is told which paths a rebuild changed', {
    with-socket(-> $reload, $messages {
      $messages.receive;
      $reload.notify(['posts/hello.html']);

      expect($messages.receive<paths>).to.eq(['posts/hello.html']);
    });
  }

  it 'is told the version each change produced', {
    with-socket(-> $reload, $messages {
      $messages.receive;
      $reload.notify(['posts/hello.html']);

      expect($messages.receive<version>).to.eq(1);
    });
  }
}
