# vim:filetype=perl

use 5.014;
use strict;
use warnings;

use Mojolicious::Lite;
use Encode qw(decode_utf8 encode_utf8);
use Digest::MD5 qw(md5_hex);
use Path::Class;
use File::Slurp;
use Text::VimColor;

my $data_root = dir('./data')->absolute;
$data_root->mkpath;

get '/' => 'index';

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

    my $data = $self->param('text');
    my $hash = substr(md5_hex(encode_utf8($data)), 0, 6);
    write_file($data_root->file($hash)->stringify, encode_utf8($data));
    $self->redirect_to($self->url_for("/$hash")->to_abs);
};

get '/source' => sub {
    my $self = shift;
    my $syntax = Text::VimColor->new(
        string         => scalar(read_file('app.psgi')),
        filetype       => 'perl',
        html_full_page => 1,
    );
    $self->res->code(200);
    $self->res->headers->content_type('text/html');
    $self->res->body($syntax->html);
};

under sub {
    my $self = shift;
    $self->stash( filetype_list => [
        [ 'html', 'HTML' ],
        [ 'perl', 'Perl' ],
        [ 'python', 'Python' ],
        [ 'javascript', 'JavaScript' ],
    ]);
    $self->stash( filetype => $self->param('filetype')//'' );
    $self->stash(wrap => 0);
    return 1;
};

get '/:hash' => [ hash => qr/[a-f0-9]{6}\.txt$/ ] => sub {
    my $self = shift;

    my $file = $data_root->file($self->param('hash') =~ s/\.txt$//r);
    return unless $file->stat;

    $self->res->code(200);
    $self->res->headers->content_type('text/plain');
    $self->res->body(decode_utf8(scalar(read_file($file->stringify))));
};

get '/:hash' => [ hash => qr/[a-f0-9]{6}$/ ] => sub {
    my $self = shift;
    my $hash = $self->param('hash');

    my $file = $data_root->file($hash);
    return unless $file->stat;
    my $data = decode_utf8(scalar(read_file($file->stringify)));

    my $syntax = Text::VimColor->new(
        string         => $data,
        filetype       => $self->param('filetype'),
    );

    if ($self->param('wrap')) {
        $self->stash(wrap => 1);
    }

    $self->render('pasted', content => $syntax->html, hash => $hash);
};

app->start;

__DATA__
@@index.html.ep
<!DOCTYPE html>
<html>
    <head>
        <title>paste.dollyfish.net.nz</title>
    </head>
    <body>
        <h1>paste.dollyfish.net.nz</h1>
        <form method="post">
            <input type="submit" value="Paste">
            <br>
            <textarea name="text" cols="80" rows="25"></textarea>
            <br>
            <input type="submit" value="Paste">
        </form>
    </body>
</html>
@@pasted.html.ep
<!DOCTYPE html>
<html>
    <head>
        <title>paste.dollyfish.net.nz</title>
        <style>
            body { color: black; background: white none }
            a:link { color: #00F; background: white none }
            a:visited { color: #909; background: white none }
            a:hover { color: #F00; background: white none }
            a:active { color: #F00; background: white none }
            .synComment    { color: #0000FF }
            .synConstant   { color: #FF00FF }
            .synIdentifier { color: #008B8B }
            .synStatement  { color: #A52A2A ; font-weight: bold }
            .synPreProc    { color: #A020F0 }
            .synType       { color: #2E8B57 ; font-weight: bold }
            .synSpecial    { color: #6A5ACD }
            .synUnderlined { color: #000000 ; text-decoration: underline }
            .synError      { color: #FFFFFF ; background: #FF0000 none }
            .synTodo       { color: #0000FF ; background: #FFFF00 none }
            #controls {
                position: fixed;
                background: #fff;
                border: 1px solid #ccc;
                box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5);
                border-radius: 5px;
                padding: 5px 10px;
                top: 20px;
                right: 20px;
            }
            pre.wrap {
                max-width: 60em;
                white-space: pre-wrap;
            }
        </style>
    </head>
    <body>
        <div id="controls">
            <form method="get" action="">
                <select name="filetype" onchange="document.forms[0].submit()">
                    <option value="">Auto detect</option>
% for my $ft ( @$filetype_list ) {
                    <option <%== $ft->[0] ~~ $filetype ? 'selected ' : '' %>value="<%= $ft->[0] %>"><%= $ft->[1] %></option>
% }
                </select>
                <a href="<%= url_for('hash', hash => $hash . '.txt') %>">raw</a>
            </form>
        </div>
% if ($wrap) {
        <pre class="wrap"><%== $content %></pre>
% } else {
        <pre><%== $content %></pre>
% }
    </body>
</html>