package App::Commentry;

use aliased 'App::Commentry::CommentStore';
use FindBin;
use HTML::Zoom;
use Web::Simple;

sub default_config {
  (
    store_dir => $FindBin::Bin.'/../store/comments',
    template_dir => $FindBin::Bin.'/../share/html',
  )
}

has comment_store => (
  is => 'lazy', handles => { 'comments_for' => 'get' }
);

sub _build_comment_store {
  my $self = shift;
  my $store_dir = $self->config->{store_dir};
  die "Comment Store directory ${store_dir} does not exist"
    unless -d $store_dir;
  CommentStore->new(base_dir => $self->config->{store_dir});
}

has template_dir => (
  is => 'lazy'
);

sub _build_template_dir {
  my $self = shift;
  my $template_dir = $self->config->{template_dir};
  die "template_dir ${template_dir} does not exist"
    unless -d $template_dir;
  $template_dir;
}

sub dispatch_request {
  my ($self) = @_;
  sub (/fragments/*/**) {
    my ($self, $action, $path) = @_;
    return unless $action eq 'show' or $action eq 'add';
    return unless my $set = $self->comments_for({ path => $path });
    $self->${\"_fragment_${action}"}($set);
  }
}

sub _fragment_show {
  my ($self, $set) = @_;
  sub (GET) {
    $self->_zoom_response(fragment_show => sub {
      $_->select('.comment')
        ->repeat($set->map(sub {
            my ($comment) = @_;
            sub {
              $_->select('.comment-title')->replace_content($comment->title)
                ->select('.comment-body')->replace_content($comment->body)
            }
          }));
    });
  }
}

sub _zoom_response {
  my ($self, $template, $apply) = @_;
  my $zfh = ($self->{zoom_cache}{$template} ||= do {
    HTML::Zoom->from_file($self->template_dir.'/'.$template.'.html')
  })->apply($apply)->to_fh;
  [ 200, [ 'Content-type' => 'text/html' ], $zfh ];
}

1;
