#!/usr/bin/env perl
use v5.16.3;

use strictures 1;
use FindBin '$Bin';
use Path::Tiny;
use File::ShareDir ':ALL';

use App::skryf::Cfg;
use App::skryf::Util;
use App::skryf::Post;
use App::skryf::PostList;

use Mojolicious::Lite;

our $VERSION = '0.006'; # VERSION

###############################################################################
# Setup configuration
###############################################################################
my $cfgfile = path($ENV{HOME}, ".skryf.conf");

path(dist_dir('App-skryf'), "skryf.conf")->copy($cfgfile)
  unless $cfgfile->exists;

plugin 'Config' => {file => $cfgfile};

my $cfghash = app->config->{skryfcfg} || +{};

# Load extra plugins
for (keys $cfghash->{extra_modules}) {
    plugin "$_" if $cfghash->{extra_modules}{$_} > 0;
  }

# Setup template and static paths
my $template_directory = $cfghash->{template_directory};
$template_directory = path(App::skryf::Util->sformat($template_directory, bindir => $Bin));

my $media_directory = $cfghash->{media_directory};
$media_directory = path(App::skryf::Util->sformat($media_directory, bindir => $Bin));

if ($template_directory->is_dir) {
    push @{app->renderer->paths}, $template_directory;
}
else {
    push @{app->renderer->paths}, path(dist_dir('App-skryf'), 'templates');
}

if ($media_directory->is_dir) {
    push @{app->static->paths}, $media_directory;
}
else {
    push @{app->static->paths}, path(dist_dir('App-skryf'), 'public');
}

# use App::skryf::Command namespace
push @{app->commands->namespaces}, 'App::skryf::Command';

###############################################################################
# Pull all blog posts
###############################################################################
my $postdir = $cfghash->{post_directory} || '%homedir%/blog/posts';
$postdir = App::skryf::Util->sformat($postdir, bindir => $Bin);
my $postlist = App::skryf::PostList->from_dir($postdir);

###############################################################################
# Pull static pages
###############################################################################
my $staticdir = $cfghash->{static_directory} || '%homedir%/blog/static';
$staticdir = App::skryf::Util->sformat($staticdir, bindir => $Bin);
my $staticlist = App::skryf::PostList->from_dir($staticdir);

my $skryfcfg = App::skryf::Cfg->new(%$cfghash);
helper skryfconf => sub {$skryfcfg};

get '/' => sub {
    my $self = shift;

    $self->stash(postlist => $postlist->scan);

    my $tmpl = $cfghash->{index_template} || 'index';
    $self->render($tmpl);
};

# Category feeds
get '/feeds/:category/atom.xml' => sub {
    my $self     = shift;
    my $category = $self->param('category');
    my $_posts   = $postlist->scan;
    $self->stash(postlist => $_posts->by_cat($category));
    $self->render(template => 'atom', format => 'xml');
};

# atom.xml
get '/atom.xml' => sub {
    my $self = shift;

    my $_posts = $postlist->scan;

    $self->stash(postlist => $_posts->by_date);
    $self->render(template => 'atom', format => 'xml');
};

get '/:staticpage' => sub {
    my $self = shift;
    my $staticpage = $self->param('staticpage');
    my $tmpl = $cfghash->{static_template} || 'static';
    my $post = $staticlist->get($staticpage);
    $self->stash(post => $post);
    $self->render($tmpl);
};

get '/post/:id' => sub {
    my $self = shift;

    my $id = $self->param('id');
    unless ($id =~ /^[A-Za-z0-9_-]+$/) {
        $self->render(text => 'Invalid post name!', status => 404);
        return;
    }

    my ($post, $retry);
  FETCH_POST: {
        $post = $postlist->get($id);

        unless ($post) {
            if ($retry) {
                $self->render(text => 'No such post!', status => 404);
                return;
            }
            ## FIXME try to load this specific post instead of re-scanning
            $postlist->scan;
            ++$retry;
            redo FETCH_POST;
        }
    }

    $self->stash(post => $post);

    my $tmpl = $cfghash->{post_template} || 'post';
    $self->render($tmpl);
};

###############################################################################
# START THE PARTY
###############################################################################
app->secret("WHO CARES RITE?");
app->start;

__END__

=head1 NAME

skryf - blogging gateway

=head1 DESCRIPTION

This is where the magic happens.

=cut
