#!/usr/bin/perl -w

# Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer. 
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution. 
# 3.  Neither the name of Apple Inc. ("Apple") nor the names of
#     its contributors may be used to endorse or promote products derived
#     from this software without specific prior written permission. 
#
# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Script to do file renaming.

use strict;
use File::Find;
use FindBin;
use lib $FindBin::Bin;
use webkitdirs;
use VCSUtils;

setConfiguration();
chdirWebKit();

my %words;

# find all files we want to process

my @paths;
find(\&wanted, "Source/JavaScriptCore");
find(\&wanted, "Source/WebCore");
find(\&wanted, "WebKit");
find(\&wanted, "Source/WebKit2");

sub wanted
{
    my $file = $_;

    if ($file eq "icu") {
        $File::Find::prune = 1;
        return;
    }

    if ($file =~ /^\../) {
        $File::Find::prune = 1;
        return;
    }

    return if $file =~ /^ChangeLog/;
    return if -d $file;

    push @paths, $File::Find::name;
}

my %renames = (
);

my %renamesContemplatedForTheFuture = (
);

# rename files

my %newFile;
for my $file (sort @paths) {
    my $f = $file;
    $f = "$1$renames{$2}" if $f =~ /^(.*\/)(\w+\.\w+)$/ && $renames{$2};
    $newFile{$file} = $f if $f ne $file;
}

for my $file (sort @paths) {
    if ($newFile{$file}) {
        my $newFile = $newFile{$file};
        print "Renaming $file to $newFile\n";
        scmMoveOrRenameFile($file, $newFile);
    }
}

# change all file contents

for my $file (sort @paths) {
    $file = $newFile{$file} if $newFile{$file};
    my $contents;
    {
        local $/;
        open FILE, $file or die;
        $contents = <FILE>;
        close FILE;
    }
    my $newContents = $contents;

    for my $from (keys %renames) {
        $newContents =~ s/\b\Q$from\E(?!\w)/$renames{$from}/g; # this " unconfuses Xcode syntax highlighting
    }

    if ($newContents ne $contents) {
        open FILE, ">", $file or die;
        print FILE $newContents;
        close FILE;
    }
}
