#!/usr/bin/perl
use strict;     #good code includes these checks
use warnings;
use feature "say"; #for say

#equivalent to:
#   Larry Hastings - Solve Your Problem With Sloppy Python - PyCon 2018
#       Hastings is a well respected core developer.
#
#   When I last looked this was available at:
#       https://www.youtube.com/watch?v=Jd8ulMb6_ls
#
#   Renames all the .mp3 files in the rogues/ directory to a format
#   that he prefers.
#
#   My list of files may not be identical to his, but is close enough
#   for the purposes here.  Any differences are caused by when I visited
#   the site with the files.  My files are merely empty files with the
#   chosen names since the contents should not be changed by a rename 
#   and we do not need content.

my @list = <rogues/*mp3>; #all file names in rogues that end .mp3
    #he needed to do an ls to make the list and then
    # cut and paste this into the script and then split 
    # that string into the list he needed!  He even 
    # needed to use .strip().split('\n').  Perl just does it.
    # Remember the diamond format <literal> generates a list
    # of file names that match the literal.
    
#we now have an array with all the file names
# names are like:
#   rogues/RoguesGallery451025019Murder.mp3
   
for my $this1 (@list) {  #let's deal with each name
    #file names are like:
    #   rogues/RoguesGallery460707055CabinOnLake.mp3
    #    being:
    #       the directory
    #       the year, month and day recorded
    #       a sequence number, if present
    #       the file title
    #       .mp3
                
    if (my @fields =    #make a note of each field matched into @fields
      $this1 =~         #compare this file name with the regEx
        #generally I do not split a RegEx over multiple lines like this
        # but here it allows us to comment as we go and so makes sense
        m[              #perform a match, as specified by the m
                        # and use the alternate delimters [] so
                        # we can search for /      
        ^rogues/RoguesGallery #need to start with this text
        (\d\d)(\d\d)(\d\d) #grab the year, month and day
        (\d{2,3})?      #grab the 2 or 3 digit sequence, if any
                        # the ? specifying 0 or 1 times
        (.*)            #the title
        \.mp3           #followed by .mp3
        $               #which must anchor to the end of the string
        ]x              #end the regEx and specify x mode which allows 
                        # white space and comments
        ) {             #the comparison/assignment ends
        
        # we are here, so matched and @fields:
        #  [0] - the year - without the century
        #  [1] - month
        #  [2] - day
        #  [3] - sequence - if present
        #  [4] - name of episode
    
        if (!$fields[3]) {$fields[3] = '000'} #if there was no sequence
                # technically if it was 0 too

        while ($fields[4] =~ s/([^ ])([A-Z])/$1 $2/) {;}   
            # make CabinOnLake into Cabin On Lake
            # We look for upper case NOT preceeded by a space and
            #  substitute with what was there, but with a space between
            #  We need to repeat with the while because of an
            #  issue with "ManIDidntKill" etc where the nI would
            #  cause a skip of the ID.
            # The while will contiue until there are no more to
            # do since the substitution also returns a true/false
           
        #fix the couple of special cases, this is essentially
        # copied from the Python which also has a special case
        $fields[4] =~ s/Theres/There's/g;
        $fields[4] =~ s/Didnt/Didn't/g;

        #format the new version of the file name
        my $newName = sprintf("rogues/%03d 19%02d%02d%02d %s",
                    $fields[3], #sequence number
                    $fields[0], #year
                    $fields[1], #month
                    $fields[2], #day
                    $fields[4], #corrected title
                );
            #NOTE: I did place a comma after the last entry and this
            #   seems to make no sense.  This technique allows me to 
            #   rearrange lines later and Perl is smart enough not to be
            #   bothered by the non-existent argument and ignores it

        say "renamed $this1 as:\n   $newName";
        #rename($this1,$newName);
        #  Actually, at this time we have the rename patched out
        #  so that we can re-run for testing

    }
    else { #note the Python code does not check for this exception
        die "File name appears bad: $this1";
    }
}
