#!/usr/bin/perl

use strict;

my $svnlook = '"c:\Program Files\subversion\bin\svnlook.exe"';

my $repos = $ARGV[0];
my $txn = $ARGV[1];
my @added; # Each added path put here.
my %tree;  # The file tree as a hash, index lower cased name, value actual name.
my $cmd;   # Command being executed.

# Get a list of added files.
local *SVNLOOK;
$cmd = $svnlook . ' changed "' . $repos . '" --transaction ' . $txn;
#open(SVNLOOK, '-|:utf8', $cmd) || die($cmd);
open(SVNLOOK, '-|', $cmd) || die($cmd);
while (<SVNLOOK>) {
  chomp;
  if (/^A\s+(\S.*)/) {
    push @added, $1;
  }
}
close SVNLOOK;

# Get the shortest directory name which has changed, this will be the path
# into the repository to use to get the history.
$cmd = $svnlook . ' dirs-changed "' . $repos . '" --transaction ' . $txn;
#open(SVNLOOK, '-|:utf8', $cmd) || die($cmd);
open(SVNLOOK, '-|', $cmd) || die($cmd);
my $shortest=999999;
my $changed;
while (<SVNLOOK>) {
  chomp;
  if (length($_) < $shortest) {
    $changed = $_;
    $shortest = length($_);
  }
}
close SVNLOOK;

# Use the history of $changed path to find the revision of the previous commit.
$cmd = $svnlook . ' history "' . $repos . '" "' . $changed . '"';
#open(SVNLOOK, '-|:utf8', $cmd) || die($cmd);
open(SVNLOOK, '-|', $cmd) || die($cmd);
my $lastrev;
while (<SVNLOOK>) {
  chomp;
  if (/(\d+)/) {
    $lastrev = $1;
    last;
  }
}

# Get the file tree at the previous revision and turn the output into
# complete paths for each file.
my @path;
$cmd = $svnlook . ' tree "' . $repos . '" "' . $changed . '" --revision ' . $lastrev;
#open(SVNLOOK, '-|:utf8', $cmd) || die($cmd);
open(SVNLOOK, '-|', $cmd) || die($cmd);
while (<SVNLOOK>) {
  chomp;
  next if (/^\/$/); # Ignore the root node.
  if (/^(\s+)(.*)\/$/) { # Is a directory.
    $#path = length($1)-2; # Number of spaces at start of line is nest level.
    push @path, $2;
    my $name = join('/', @path) . '/';
    $tree{lc($changed.$name)} = $name; # Index the hash with case folded name.
  } elsif (/^\s+(.*)$/) {  # This is a real file name, not a directory.
    my $name = join('/', @path) . '/' . $1;
    $tree{lc($changed.$name)} = $name; # Index the hash with case folded name.
  }
}
close SVNLOOK;

my $failmsg;
foreach my $newfile (@added) {
  if (exists($tree{lc($newfile)})) {
    $failmsg .= "\n  $newfile already exists as " . $tree{lc($newfile)};
  }
}
if (defined($failmsg)) {
  die "\nFile name case conflict found:\n" . $failmsg . "\n";
}
exit 0;

