package App::SCS::Plugin::Core;

use Module::Runtime qw(use_module);
use IO::All;
use Moo;
no warnings::illegalproto;
use Safe::Isa;

with 'App::SCS::Role::Plugin';

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

sub _build_templates {
  my ($self) = @_;
  return use_module('App::SCS::PageSet')->new(
    base_dir => io->dir($self->app->share_dir)->catdir('templates'),
    plugin_config => {
      plugin_map => $self->app->page_plugin_config->{plugin_map}
    }
  );
}

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

sub _build_includes {
  my ($self) = @_;
  return use_module('App::SCS::PageSet')->new(
    base_dir => io->dir($self->app->config->{share_dir})->catdir('includes'),
  );
}

sub page_plugins {
  my ($self) = @_;
  PageList => 'App::SCS::Plugin::Core::PagePlugin::PageList',
  RemovePlugin => 'App::SCS::Plugin::Core::PagePlugin::RemovePlugin',
  Template => {
    class => 'App::SCS::Plugin::Core::PagePlugin::Template',
    config => sub { templates => $self->templates },
  },
  Include => {
    class => 'App::SCS::Plugin::Core::PagePlugin::Include',
    config => sub { includes => $self->includes },
  },
  PageData => 'App::SCS::Plugin::Core::PagePlugin::PageData',
}

sub default_page_plugins {
  Template => {
    name => 'layout',
  },
  PageData => {},
}

sub page_dispatchers {
  my ($self) = @_;
  sub (/) {
    $self->pages->get({ path => 'index' });
  },
  sub (/**) {
    [ 302, [ 'Location' => "/$_[1]/" ], [] ]
  },
  sub (/**:path/) {
    $self->pages->get({ %_ })
  },
  sub () {
    $self->pages
         ->get({ path => 'error_404' })
         ->$_call_if_object(with_plugin_config => Status => 404);
  },
}

sub provides_pages {
  my ($self) = @_;
  "/", map "$_/", $self->pages->all_paths;
}

1;
