#!/usr/bin/perl

# from: https://gist.github.com/siracusa/5720437eeedec02a7171


use strict;
use warnings;
use Getopt::Std;
use v5.16;

our $opt_q;
our $opt_n;
our $opt_f;
our $opt_r;
our $opt_h;
our $opt_A;
our $opt_d;

getopts('dqnfrhA');


our $quiet = $opt_q;
our $dryrun = $opt_n;
our $force = $opt_f;
our $help = $opt_h;
our $regexp = $opt_r;
our $dotfiles = $opt_A;
our $dirs = $opt_d;

sub usage {
    my $ret = $_[0] || 0;

    say "Usage:";
    say "       plrename [-dfqn] <expression> <file>...";
    say "       plrename -r [-dfqnA] <expression> <file regexp>";
    say "";
    say "       -f      Rename without asking";
    say "       -q      Quiet (do not print 'from -> to' message)";
    say "       -n      Dry run (do not rename, just print what would be renamed";
    say "       -r      Rename files matching regexp";
    say "       -A      Regexp match all files (including dotfiles)";
    say "       -d      Rename dirs too";

    exit($ret);
}

if ($help) {
    usage(0);
}
if (@ARGV < 2) {
    usage(2);
}


no strict;
my $op = eval 'sub { ' . (shift) . ' }'; # crazily dangerous - type carefully!
die $@ if $@;
use strict;

sub ask_yn {
    my $prompt = shift;
    if ($prompt) {
        print $prompt . "\n";
    }
    my $response = <STDIN>;
    if (substr($response, 0, 1) eq 'y') {
        return 1;
    }
    return 0;
}

my @files;

if ($regexp) {
    opendir(my $dh, ".") || die "Can't opendir current dir: $!";
    # $ARGV[0] was originally the $op but we shifted that so now it's the regexp
    @files = grep { /$ARGV[0]/ } readdir($dh);
    closedir($dh);
    @files = grep { $_ ne '.' && $_ ne '..' } @files;
    if (! $dotfiles) {
        @files = grep { substr($_, 0, 1) ne '.' } @files;
    }
}
else {
    @files = @ARGV;
}

for (@files) {
    my $old = $_;

    if (!$dirs && -d $old) {
        say "skipping dir $old" unless $quiet;
        next
    }

    $op->($_);

    my $new = $_;

    unless($old eq $new) {
        if (! $force && ! $dryrun) {
            if (! ask_yn("Rename $old -> $new ?")) { next }
        }
        if ($dryrun) {
            say "[dry-run] $old -> $new";
        } else {
            say "$old -> $new" unless $quiet;
            rename($old, $new) or warn "Couldn't rename $old -> $new - $!\n";
        }
    }
}

