#! /opt/perl/bin/perl

# ABSTRACT: An interactive web-based Dancer-powered inspection tool for Moose-based code.
# PODNAME: mexi


use Dancer;
use File::Find::Rule;
use File::ShareDir    qw/ dist_dir /;
use File::Spec;
use Hash::Merge       qw/ merge /;
use Modern::Perl;
use MooseX::amine;
use Template;
use Try::Tiny;

my $dir    = dist_dir('MooseX-amine');
my $public = ( -e './share/public') ? File::Spec->rel2abs('./share/public') : "$dir/public";
my $views  = ( -e './share/views' ) ? File::Spec->rel2abs('./share/views')  : "$dir/views";

set access_log   => 1;
set appdir       => $dir;
set appname      => 'MooseX::amine';
set charset      => "UTF-8";
set layout       => 'main';
set log          => 'warning';
set logger       => 'console';
set public       => $public;
set show_errors  => 1 ;
set template     => 'template_toolkit';
set views        => $views;
set warnings     => 1;

my %standard_mooosex_amine_args = (
  include_private_attributes => 1 ,
  include_private_methods    => 1 ,
);

get '/_list' => sub {
  my $dir   = File::Spec->rel2abs( './' );
  my @files = File::Find::Rule->file()->name('*.pm')->in('./');

  my %tree;
  foreach my $file ( @files ) {
    next if $file =~ /^\./;

    my @parts = split '/' , $file;
    my $hash  = { pop @parts => $file };

    while ( my $part = pop @parts ) {
      my $new_hash = { $part => $hash };
      $hash = $new_hash;
    }

    %tree = %{ merge( $hash , \%tree )  };
  }
  template 'list' => { files => \@files  , tree => \%tree , dir => $dir };
};

get '/_show/name/*' => sub {
  my( $name ) = splat;

  try {
    my $mex = MooseX::amine->new({
      module => $name ,
      %standard_mooosex_amine_args ,
    });
    template 'show' => {
      mex  => $mex->examine ,
      name => $name
    };
  }
  catch { debug $name };
};

get qr{^/_show/(.*)} => sub {
  my( $file ) = splat;

  try {
    my $mex = MooseX::amine->new({
      path => $file ,
      %standard_mooosex_amine_args ,
    });
    template 'show' => {
      mex  => $mex->examine ,
      name => $mex->module };
  }
  catch {
    if ($_ =~ /^Can't locate object method "meta" via package/ ) {
      template 'show' => { no_mex =>1 , message => 'Not a Moose object' };
    }
    else { die $_ }
  };
};

get '/_show' => sub {
  template 'show' => { no_mex => 1 };
};

get '/' => sub { template 'index' => {} => { layout => 0 } };

Dancer->dance;

__END__

=pod

=encoding UTF-8

=head1 NAME

mexi - An interactive web-based Dancer-powered inspection tool for Moose-based code.

=head1 VERSION

version 0.07

=head1 SYNOPSIS

    # cd into a directory that has a Moose-based distribution
    mexi

    # can give a specific port with '--port xxxx' -- default is 3000

    # browse to http://localhost:3000 and check out your code

=head1 DESCRIPTION

Ever had the problem of needing to get up to speed on a large Moose-based hunk
of code? Feel like you're lost in a twisty little maze of attributes, methods,
roles, and classes? Worried about grues? Maybe C<mexi> can help.

=head1 AUTHOR

John SJ Anderson <john@genehack.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2020 by John SJ Anderson.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
