#!/usr/bin/perl
use strict;
use warnings;

use Time::Piece;
use Data::Dump;

my $InputFile = "/tmp/files";
my $FindCommand = "find . -print > $InputFile";
my %FileList = ();
my %FileSize = ();
my $RepoDir = "/var/www/html/jdownloads";
my $UnixFile = "$RepoDir/LatestFilesUnix.txt";
my $OutputFile = "$RepoDir/LatestFiles.txt";
my $ConversionCommand = "/usr/bin/perl -p -e 's/\n/\r/g' < LatestFilesUnix.txt > LatestFiles.txt";
my $NumFiles = 0;
my $InputFileSorted = "/tmp/filessorted";
my $VERSION = "1.2.4";
my $filename = "/root/.latestrc";
my $ServerName = "";
my $EDITOR = "nano";
my $SORTMODE = "name";
my @DateSort;
my $DEBUGMODE = "no";

# See if the EDITOR env var is set, use it if so
if ($ENV{'EDITOR'})
{
        $EDITOR = $ENV{'EDITOR'};
}

sub DebugPrint
{
	if ($DEBUGMODE eq "debug")
	{
		print $_;
	}
}

print  "latestfiles file listing app by MarisaG v$VERSION\n";
print  "===================================================\n";

my $defaultfile = <<'END_TEMPLATE';
# Put Server name here:
Classic Macs OSX Cat Editions
# Put default mode here: "date" or "name"
date
# Get more apps like this at https://marisa-apps.retro-os.live
END_TEMPLATE

if (! -f $filename)
{
	print "Settings file $filename not found, creating it...\n";
	open(FILEOUT, '>', $filename) or die $!;
	#        print FILEOUT "$defaultfile\n";
        print FILEOUT "$defaultfile";
	close(FILEOUT);
	system("$EDITOR $filename");
}

open(FILEIN, '<', $filename) or die $!;
my $LastLine = 0;
while(<FILEIN>)
{
	# print $_;
	if ((substr($_, 0, 1) eq "#") || ($_ eq ""))
	{
		# skip over comments
		next;
	}
	chop();
	if ($LastLine == 0)
	{
		$ServerName = $_;
		$LastLine++;
		DebugPrint("saw server name '$ServerName'\n");
		next;
	}
	if ($LastLine == 1)
	{
		$SORTMODE = $_;
		DebugPrint("saw sortmode '$SORTMODE'\n");
		if (($SORTMODE ne "date") && ($SORTMODE ne "name"))
		{
			$SORTMODE = "name";
		}
		$LastLine++;
	}
}
close(FILEIN);

my $num_args = $#ARGV + 1;
if ($num_args != 0)
{
        if ($ARGV[0] eq "prefs")
        {
                system("$EDITOR $filename");
                exit 0;
        }
        elsif (($ARGV[0] eq "help") || ($num_args > 1))
        {
                print "Usage: latestfiles [prefs|help|date|debug]\n";
                exit 0;
        }
        elsif ($ARGV[0] eq "date")
        {
                DebugPrint("SORTMODE = $SORTMODE\n");
                $SORTMODE = "date";
        }
        elsif ($ARGV[0] eq "name")
        {
                DebugPrint("SORTMODE = $SORTMODE\n");
                $SORTMODE = "name";
        }
        elsif ($ARGV[0] eq "debug")
        {
                DebugPrint("DEBUGTMODE = $DEBUGMODE\n");
                $DEBUGMODE = "debug";
        }
}
print  "Sorting by: $SORTMODE\n";

print "Scanning for files: ";
chdir($RepoDir);
system("$FindCommand");
system("sort --output=$InputFileSorted $InputFile");

open(my $fh, '<', $InputFileSorted)
  or die "Could not open file '$InputFileSorted' $!";
 
while (my $row = <$fh>)
{
	chomp $row;
	# print "row = '$row'\n";
	my $shortname = substr($row, 0, 3);
	# print "shortname = '$shortname'\n";
	if (($row eq ".")||($row eq "..")||($row eq "./Desktop Folder")||($row eq "./LatestFiles.txt")||($row eq "./LatestFilesUnix.txt")||($shortname eq "./_"))
	{
		DebugPrint("Skipping $row\n");
		next;
	}
	if (-d $row)
	{
		DebugPrint("$row was a directory\n");
		next;
	}
	if ((index($row, "rsrc") != -1)||(index($row, "index.html") != -1))
	{
		DebugPrint("submatch $row\n");
		next;
	}
	#my $substring = $row;
	#if (my $mystring =~ /\Q\.rsrc\E/)
	#if (my $mystring =~ /rsrc/)
	#{
	#	print qq("$mystring" contains ".rsrc"\n);
	#	next;
	#}

	$row = substr($row, 2);
	# print "new $row\n";
	my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
		$atime,$mtime,$ctime,$blksize,$blocks)
		= stat($row);
	if (! defined($mtime))
        {
		print "File is '$row'\n";
		exit 0;
        }
	# print "modify time: $mtime\n";
	$size = fmt2($size);
	if ($SORTMODE eq "date")
	{
		$FileList{$mtime} = $row;
		$FileSize{$mtime} = $size;
		DebugPrint("FileList = $FileList{$mtime}\n");
	}
	else
	{
		$FileList{$row} = $mtime;
	}
	$NumFiles += 1;

	# print "$FileList{$mtime}\n";
	# print "$FileList{$row}\n";
	# print "$row\n";
}

print "Done\nProcessing Files: ";
foreach my $mydate (reverse sort keys %FileList) 	# ZZZ
{
	# print "$mydate\n";
	my $HumanDate = localtime($mydate)->strftime('%F %T'); # adjust format to taste
	if (! defined($mydate))
	{
		DebugPrint("mydate doesnt exist\n");
	}
	if (! defined($FileList{$mydate}))
	{
		# print "mydate = $mydate\n";
		DebugPrint("FileList doesnt exist\n");
	}
	if (! defined($FileSize{$mydate}))
	{
		# print "$FileSize{$mydate}\n";
		DebugPrint("FileSize doesnt exist\n");
		$FileSize{$mydate} = 0;
	}
	#print "$FileSize{$mydate}\n";
	#print "$HumanDate\t$FileSize{$mydate}\t$FileList{$mydate}\n";	# ZZZ
	push (@DateSort, "$HumanDate\t\t$FileSize{$mydate}\t\t$FileList{$mydate}");
}

close ($fh);
sub fmt2 {
   my ($bytes) = @_;
   my @units = qw ( B KB MB GB TB );
   #divide by 1024 whilst above
   while ( $bytes > 1024 ) {
      shift(@units); #drop one of the units prefixes until one 'fits'. 
      $bytes /= 1024;
   }
   return sprintf( '%.3g%s', $bytes, $units[0] );
}
sub fmtsize
{
        my $bytes = shift;

        my @variations = map { sprintf '%.3g%s', $bytes/1024 ** $_->[1], $_->[0] }
            [ " bytes" => 0 ],
            [ KB => 1 ],
            [ MB => 2 ],
            [ GB => 3 ];

        dd \@variations;

        return ( sort { length $a <=> length $b } @variations ) [0];
}

open($fh, '>', $UnixFile)
  or die "Could not open file '$UnixFile' $!";

my $HumanDate = localtime()->strftime('%F %T'); # adjust format to tasprint $fh "Last Scan: $HumanDate\n"
print $fh "Last Scan: $HumanDate\n";
print $fh "Files found: $NumFiles\n";
print $fh "$ServerName Latest Files v$VERSION\n";
print $fh "===================================================\n";
print $fh "Upload Date\t\t\tSize\t\tFile Name\n";
print $fh "-------------\t\t\t---------\t----------\n";

if ($SORTMODE eq "date")
{
	foreach(@DateSort)
	{
		# print "Saw $_\n";
		print $fh "$_\n";
	}
	system($ConversionCommand);
	print "Done\n";
	exit 0;
}

open(my $filelist, '<', $InputFileSorted)
  or die "Could not open file '$InputFileSorted' $!";
while(my $CurFile = <$filelist>)
{
	chomp($CurFile);
	if (length($CurFile) <= 2)
	{
		next;
	}
	$CurFile = substr($CurFile, 2);
	# print "File is '$CurFile'\n";
	#	my $HumanDate = localtime(my $name)->strftime('%F %T'); # adjust format to taste
	if (($CurFile eq ".")||($CurFile eq "..")||($CurFile eq "./Desktop Folder")||($CurFile eq "./LatestFiles.txt")||($CurFile eq "./LatestFilesUnix.txt")||(substr($CurFile, 0, 1) eq "_"))
        {
                next;
        }
        if (-d $CurFile)
        {
                DebugPrint("$CurFile was a directory\n");
                next;
        }
        if (index($CurFile, "rsrc") != -1)
        {
                DebugPrint("Saw rsrc in '$CurFile'\n");
                next;
        }
	if ($CurFile eq "")
	{
		next;
	}

	my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
		$atime,$mtime,$ctime,$blksize,$blocks)
		= stat($CurFile);
	$HumanDate = localtime($CurFile)->strftime('%F %T'); # adjust format to taste
	$mtime = localtime($mtime);
	$size = fmt2($size);
	print $fh "$mtime\t$size\t\t$CurFile\n";
}
close($filelist);
print "Done\n";

##foreach my $name (reverse sort keys %FileList)
#foreach my $name (sort keys %FileList)
#{
#	$HumanDate = localtime($name)->strftime('%F %T'); # adjust format to taste
#	print $fh "$HumanDate\t$FileList{$name}\n";
#}
#close ($fh);
system($ConversionCommand);
exit 0;
