use lib 'lib';
use lib 'specs/support';
use BDD::Behave;
use BloginTest;
use Blogin::Server;

describe 'the directories under a watched tree', {
  let(:root, {
    my $dir = temp-made('watch-dirs');
    $dir.add('posts/2026').mkdir;
    $dir.add('drafts').mkdir;
    $dir
  });

  after-each { nuke(root()) }

  it 'includes the tree root itself', {
    expect(Blogin::Server::descendant-dirs(root()).map(*.absolute)).to.include(root().absolute);
  }

  it 'reaches a directory nested more than one level deep', {
    expect(Blogin::Server::descendant-dirs(root()).map(*.absolute)).to.include(root().add('posts/2026').absolute);
  }

  it 'finds every directory in the tree', {
    expect(Blogin::Server::descendant-dirs(root()).elems).to.eq(4);
  }

  it 'skips a dot directory', {
    root().add('.git').mkdir;

    expect(Blogin::Server::descendant-dirs(root()).map(*.basename)).not.to.include('.git');
  }

  it 'is empty for a directory that does not exist', {
    expect(Blogin::Server::descendant-dirs(root().add('nope'))).to.eq([]);
  }
}

describe 'watching a content tree', {
  let(:root, {
    my $dir = temp-made('watch-tree');
    $dir.add('posts').mkdir;
    $dir
  });

  let(:watcher, { Blogin::Server::DirWatcher.new(on-change => sub { }) });

  after-each { nuke(root()) }

  it 'registers a watcher for every directory in the tree', {
    my $watch = watcher();
    $watch.watch(root());

    expect($watch.watched-count).to.eq(2);
  }

  it 'picks up a directory created after the server started', {
    my $watch = watcher();
    $watch.watch(root());

    root().add('posts/2026').mkdir;
    $watch.rescan;

    expect($watch.watched-count).to.eq(3);
  }

  it 'does not register a directory twice', {
    my $watch = watcher();
    $watch.watch(root());
    $watch.rescan;

    expect($watch.watched-count).to.eq(2);
  }

  it 'ignores a root that does not exist', {
    my $watch = watcher();
    $watch.watch(root().add('nope'));

    expect($watch.watched-count).to.eq(0);
  }
}
