#!/usr/bin/perl

die "usage: svn_fix_properties <dir>\nsvn_fix_properties <file>\n"
    unless (@ARGV == 1);
my $target = $ARGV[0];

########################################################################

%gExtExecutable =
    (
     "bat" => 1,
     "exe" => 1,
     "sh" => 1,
     "pl" => 1,
     "py" => 1,
    );


%gExtText =
    (
     "applescript" => 1,
     "bat" => 1,
     "cmake" => 1,
     "c" => 1,
     "cpp" => 1,
     "cs" => 1,
     "csproj" => 1,
     "exp" => 1,
     "glsl" => 1,
     "h" => 1,
     "H" => 1,
     "html" => 1,
     "inc" => 1,
     "ini" => 1,
     "inl" => 1,
     "l" => 1,
     "mm" => 1,
     "msg" => 1,
     "nib" => 1,
     "pem" => 1,
     "pl" => 1,
     "plist" => 1,
     "py" => 1,
     "r" => 1,
     "rc" => 1,
     "sln" => 1,
     "strings" => 1,
     "supp" => 1,
     "txt" => 1,
     "xib" => 1,
     "xml" => 1,
     "y" => 1,
    );

%gExtTextLF =
    (
     "sh" => 1,
    );

%gExtIgnore =
    (
     "" => 1,
     "a" => 1,
     "bin" => 1,
     "BMP" => 1,
     "bmp" => 1,
     "bz2" => 1,
     "cur" => 1,
     "db2" => 1,
     "gif" => 1,
     "ico" => 1,
     "icns" => 1,
     "j2c" => 1,
     "jpg" => 1,
     "lib" => 1,
     "llm" => 1,
     "nsi" => 1,
     "png" => 1,
     "psp" => 1,
     "tga" => 1,
     "ttf" => 1,
     "xcf" => 1,
     "zip" => 1,
    );

########################################################################

if (-d $target) {
    &checkDir($target);
} elsif (-f $target) {
    &checkFile($target);
} else {
    print STDERR "'$target' does not exist.\n";
}

########################################################################

sub checkDir
{
    my ($dir) = @_;

    chdir $dir or
	die "Failed to change to directory '$d'\n";

    print STDERR "Updating from SVN.\n";
    system("svn update");

    print STDERR "Checking files.\n";
    open(SVN_DIR, "svn list -R . |") or
	die "Failed to run svn.\n";
    while (my $file = <SVN_DIR>) {
	chomp($file);
	&checkFile($file);
    }
    close SVN_DIR or
	die "Error running svn.\n";
}

########################################################################

sub checkFile
{
    my ($file) = @_;
    my $known = 0;

    my @props = &getSvnProperties($file);

    $file =~ /\.(\w+)$/;
    my $ext = $1;

    # check executable
    if (defined($gExtExecutable{$ext})) {
	&addProperty($file, "svn:executable", "true")
	    unless grep($_ eq "svn:executable", @props);
	$known = 1;
    } else {
	&delProperty($file, "svn:executable")
	    if grep($_ eq "svn:executable", @props);
    }

    # check text
    if (defined($gExtText{$ext})) {
	&addProperty($file, "svn:eol-style", "native")
	    unless grep($_ eq "svn:eol-style", @props);
	$known = 1;
    } elsif (defined($gExtTextLF{$ext})) {
	&addProperty($file, "svn:eol-style", "LF")
	    unless grep($_ eq "svn:eol-style", @props);
	$known = 1;
    } else {
	&delProperty($file, "svn:eol-style")
	    if grep($_ eq "svn:eol-style", @props);
    }

    unless ($known || defined($gExtIgnore{$ext})) {
        print STDERR "Unknown extension '$ext'\n";
	$gExtIgnore{$ext} = 1;
    }
}

########################################################################

sub getSvnProperties
{
    my ($file) = @_;
    my @props = ();
    
    open(SVN_PROPS, "svn pl '$file' |") or
	die "Failed to run svn.\n";
    while (<SVN_PROPS>) {
	(/(svn:\S+)/) and push(@props, $1);
    }
    close SVN_PROPS or
	die "Error running svn.\n";
    @props;
}

########################################################################

sub addProperty
{
    my ($file, $prop, $value) = @_;

    system("svn ps '$prop' '$value' '$file'") and
	die "Error running svn.\n";
}

sub delProperty
{
    my ($file, $prop) = @_;

    system("svn pd '$prop' '$file'") and
	die "Error running svn.\n";
}

