#!/usr/bin/env perl
use utf8;
use Modern::Perl;
use Mojolicious::Lite;
use Data::Dumper;
use Getopt::Std;

my %opts = (
	p	=>	3000,
);

getopt('p', \%opts);
say $opts{p};

my $types = Mojolicious::Types->new;

# Increase limit to 1GB
$ENV{MOJO_MAX_MESSAGE_SIZE} = 10737418240;

@{app->static->paths} = ('.');

# Route with placeholder
any '/' => sub {
	shift->redirect_to('disk');
} => 'home';
any '/disk/(*ppath)' => { ppath => '.' } => sub {
	listDir(shift);
} => 'disk';
any '/photo/(*ppath)' => { ppath => '.' } => sub {
	listPhoto(shift);
} => 'photo';


sub listPhoto {
	my $self = shift;
	my $path  = $self->param('ppath');
	
	#$path =~ s/^\///;
	$path = '.' if $path eq '';
	
	if( -d $path ) 
	{
  		say __LINE__ . ' dir';

		my ($dirs, $files) = dirContent($path);# || $self->render( text => "can't opendir $path: $!") && return;

		my @photos = grep /\.(jpg|png|gif)$/i, @$files;		
		
		#say Dumper(\@dirs);
		$self->stash( files => \@photos );
		$self->stash( dirs => $dirs );
		$self->render('photo');
	} else { 
		$self->render( text => "bad req")
	}
	
}

sub listDir {
	my $self = shift;
	my $path  = $self->param('ppath');
	
	#$path =~ s/^\///;
	$path = '.' if $path eq '';
	
	if($self->req->method eq 'POST') {
		uploadSub($self);
	}	
	
	
	$self->stash( ppath => $path );
	say __LINE__ . $path;
	if( -f $path ) {
		say 'file';
		$self->render_static($path);
		my ($ext) = $path =~ /\.(.*?)$/;
		if( my $type = $types->type(lc $ext) )
		{
			$self->res->headers->content_type( $type );
		}
	} elsif( -d $path ) 
	{
  		say __LINE__ . ' dir';

		my ($dirs, $files) = dirContent($path);# || $self->render( text => "can't opendir $path: $!") && return;
		
		#say Dumper(\@dirs);
		$self->stash( files => $files );
		$self->stash( dirs => $dirs );
		$self->render('index');
	} else { 
		$self->render( text => "bad req")
	}
}


sub dirContent {
		my $some_dir = shift;
		opendir(my $dh, $some_dir);
		my @files = ();
		my @dirs = ();
		while(readdir $dh) {
			utf8::decode($_);
			next if /^\.$/ or /^\.\.$/;
			if( -f "$some_dir/$_" ) { push @files, "$_" }
			elsif( -d "$some_dir/$_" ) { push @dirs, "$_" }
		}
		closedir $dh;
		
		return \@dirs, \@files;
}

# Multipart upload handler
sub uploadSub {
	my $self = shift;
	 
	# Check file size
	return $self->render(text => 'File is too big.', status => 200)
		if $self->req->is_limit_exceeded;
	 
	for my $file ( $self->req->upload('files') )
	{
		my $path = $self->param('ppath');
		my $size = $file->size;
		my $name = $file->filename;
		$name = checkFile($path, $name);
		$file->move_to("$path/$name");
		$self->flash(message => "Thanks for uploading $size byte file $name.");
	}
	
}; 

sub checkFile {
	my ($path, $name) = @_;
	if( -e "$path/$name" ) {
		say __FILE__ . " exists $name";
		return checkFile($path, $name . '_' );
	}
	return $name;
}

# Start the Mojolicious command system
app->start('daemon', '-l', 'http://*:3000');

__DATA__

@@ home.html.ep
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Tiny Cloud</title>
  <style>
  p { color:  navy; }
  </style>
 </head>
 <body>
 </body>
</html>

 
@@ index.html.ep
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Tiny Cloud</title>
  <style>
  p { color:  navy; }
  </style>
 </head>
 <body>

% if (my $msg = flash 'message') {
  <b><%= $msg %></b><br>
% }

<a href="<%= url_for 'disk', ppath => '' %>">Home</a>
% my $pp = ''; for my $p  (split '/', $ppath) { 
 / <a href="<%= url_for 'disk', ppath => "$pp$p" %>"><%= "$p" %></a> 
%	$pp.="$p/"; }

 
 <br>
 Dirs:<br>
 <ul>
% for my $file (sort @$dirs) {
  <li><a href="<%= url_for 'disk', ppath => "$ppath/$file" %>"> <%= $file %> </a></li>
% }
</ul>

Files: <a href=" <%= url_for 'photo', ppath => $ppath  %> ">Photos</a><br>
<ul>
% for my $file (sort @$files) {
  <li><a href="<%= url_for 'disk', ppath => "$ppath/$file" %>"> <%= $file %> </a></li>
% }
</ul>

Upload to <%= $ppath %><br>
    %= form_for '' => (enctype => 'multipart/form-data') => (method => 'POST') => begin
      %= file_field 'files', multiple => "multiple"
      %= submit_button 'Upload'
    % end
  
 </body>
</html>

@@ photo.html.ep
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Tiny Cloud</title>
  <style>
  p { color:  navy; }
  img { max-width: 30%; min-width: 100px;}
  </style>
 </head>
 <body>

% if (my $msg = flash 'message') {
  <b><%= $msg %></b><br>
% }

<a href="<%= url_for 'photo', ppath => '' %>">Home</a>
% my $pp = ''; for my $p  (split '/', $ppath) { 
 / <a href="<%= url_for 'photo', ppath => "$pp$p" %>"><%= "$p" %></a> 
%	$pp.="$p/"; }

 
 <br>
 Dirs:<br>
 <ul>
% for my $file (sort @$dirs) {
  <li><a href="<%= url_for 'photo', ppath => "$ppath/$file" %>"> <%= $file %> </a></li>
% }
</ul>

<a href=" <%= url_for 'disk', ppath => $ppath  %> ">Files</a> Photos:<br>

% for my $file (sort @$files) {
  <a href="<%= url_for 'disk', ppath => "$ppath/$file" %>"> 
  		<img src="<%= url_for 'disk', ppath => "$ppath/$file" %>"> </a>
% }

<br>
  
 </body>
</html>