#!/usr/bin/env perl

# Copyright (C) 2006, 2007, 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 Computer, 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 a rename in JavaScriptCore, WebCore, and WebKit.

use strict;
use warnings;

use File::Find;
use FindBin;
use Getopt::Long qw(:config pass_through);

use lib $FindBin::Bin;
use webkitdirs;
use VCSUtils;

setConfiguration();
chdirWebKit();

my $showHelp;
my $verbose;

my $programName = basename($0);
my $usage = <<EOF;
Usage: $programName [options]
  -h|--help                       Show this help message
  -v|--verbose                    More verbose output
EOF

my $getOptionsResult = GetOptions(
    'help|h' => \$showHelp,
    'verbose|v' => \$verbose,
);

if (!$getOptionsResult || $showHelp) {
    print STDERR $usage;
    exit 1;
}

my @directoriesToIgnoreList = (
    "expected",
    "icu",
);
my %directoriesToIgnore = map { $_ => 1 } @directoriesToIgnoreList;

# find all files we want to process

my @paths;
find(\&wanted, "Source/JavaScriptCore");
find(\&wanted, "Source/WTF");
find(\&wanted, "Source/WebCore");
find(\&wanted, "Source/WebKitLegacy");
find(\&wanted, "Source/WebKit");
find(\&wanted, "Tools/DumpRenderTree");
find(\&wanted, "Tools/TestWebKitAPI");

sub wanted
{
    my $file = $_;

    # Ignore excluded and hidden files/directories.
    if ($directoriesToIgnore{$file} or $file =~ /^\../ or $file =~ /^ChangeLog/) {
        print "Ignoring $File::Find::name\n" if $verbose;
        $File::Find::prune = 1;
        return;
    }

    return if -d $file;

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

# Setting isDOMTypeRename to 1 rather than 0 expands the regexps used
# below to handle custom JavaScript bindings.
my $isDOMTypeRename = 0;
my %renames = (
    # Renames go here in the form of:
    "ConstructorRaisesException" => "ConstructorMayThrowLegacyException",
    "GetterRaisesException" => "GetterMayThrowLegacyException",
    "GetterRaisesExceptionWithMessage" => "GetterMayThrowLegacyExceptionWithMessage",
    "RaisesException" => "MayThrowLegacyException",
    "RaisesExceptionWithMessage" => "MayThrowLegacyExceptionWithMessage",
    "SetterRaisesException" => "SetterMayThrowLegacyException",
    "SetterRaisesExceptionWithMessage" => "SetterMayThrowLegacyExceptionWithMessage",
);

my %renamesContemplatedForTheFuture = (
    "setDOMException" => "propagateException",
    "setDOMExceptionSlow" => "propagateExceptionSlowPath",

    "PassRefPtr" => "DeprecatedPassRefPtr",

    "HTMLPlugInImageElement" => "HTMLEmbeddedObjectElement",
    "isPlugInImageElement" => "isEmbeddedObjectElement",
    "isHTMLPlugInImageElement" => "isHTMLEmbeddedObjectElement",
    "toHTMLPlugInImageElement" => "toHTMLEmbeddedObjectElement",

    "DOMObject" => "JSDOMObject",

    "DateInstance" => "JSDate",
    "ErrorInstance" => "JSError",

    "TreeShared" => "TreeRefCounted",

    "StringImpl" => "SharedString",

    "RenderView" => "RenderViewport",

    "ObjcFallbackObjectImp" => "ObjCFallbackObject",
    "RuntimeObjectImp" => "ForeignObject",

    "runtime_array" => "BridgedArray",
    "runtime_method" => "BridgedFunction",
    "runtime_object" => "BridgedObject",
    "objc_runtime" => "ObjCBridge",

    "WTF_UNICODE_H" => "Unicode_h",
    "WTF_UNICODE_ICU_H" => "UnicodeICU_h",
    "UnicodeIcu" => "UnicodeICU",

    "LegacyWebArchive" => "WebArchive",
    "LegacyWebArchive_h" => "WebArchive_h",

    "NativeFunctionWrapper_h" => "JSHostFunction_h",
    "NativeFunctionWrapper" => "JSHostFunction",
    "nativeFunctionThunk" => "hostFunctionThunk",
    "nativeFunction" => "hostFunction",
    "NativeFunction" => "HostFunction",
);

# Sort the keys of the renames hash in order of decreasing length. This
# handles the case where some of the renames are substrings of others;
# i.e., "Foo" => "Bar" and "FooBuffer" => "BarBuffer".
my @sortedRenameKeys = sort { length($b) - length($a) } keys %renames;

# rename files

sub renameFile
{
    my $file = shift;

    if ($isDOMTypeRename) {
        # Find the longest key in %renames which matches this more permissive regexp.
        # (The old regexp would match ".../Foo.cpp" but not ".../JSFooCustom.cpp".)
        # This handles renaming of custom JavaScript bindings even when some of the
        # renames are substrings of others. The only reason we don't do this all the
        # time is to avoid accidental file renamings for short, non-DOM renames.
        for my $key (@sortedRenameKeys) {
            my $newFile = "";
            $newFile = "$1$renames{$2}$3" if $file =~ /^(.*\/\w*)($key)(\w*\.\w+)$/;
            if ($newFile ne "") {
                return $newFile;
            }
        }
    } else {
       $file = "$1$renames{$2}$3" if $file =~ /^(.*\/)(\w+)(\.\w+)$/ && $renames{$2};
    }
    return $file;
}

my %newFile;
for my $file (sort @paths) {
    my $f = renameFile($file);
    if ($f ne $file) {
        $newFile{$file} = $f;
    }
}

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 "Failed to open $file";
        $contents = <FILE>;
        close FILE;
    }
    my $newContents = $contents;

    if ($isDOMTypeRename) {
        for my $from (@sortedRenameKeys) {
            # Handle JavaScript custom bindings.
            $newContents =~ s/\b(JS|to|)$from/$1$renames{$from}/g;
        }
    } else {
        for my $from (@sortedRenameKeys) {
            $newContents =~ s/\b$from(?!["\w])/$renames{$from}/g; # this " unconfuses Xcode syntax highlighting
        }
    }

    # Remove the "virtual" keyword from virtual/override lines.
    # Should be a no-op but also OK to remove this any time, now that we have done it once.
    $newContents =~ s/^(\s*(\w+EXPORT\w*\s+)?)virtual ([^{;]+ override\b)/$1$3/mg;
    $newContents =~ s/^(\s*(\w+EXPORT\w*\s+)?)virtual ([^{;]+ final\b)/$1$3/mg;
    $newContents =~ s/\boverride\s+final\b/final/g;
    $newContents =~ s/\bfinal\s+override\b/final/g;

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