#!/usr/bin/env perl

# Copyright (C) 2007, 2008, 2009, 2010 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. 
#
# 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 check that source file extensions match file types in Xcode project.pbxproj files.

# TODO
# - Add support for file types other than source code files.
# - Can't differentiate between sourcecode.c.h and sourcecode.cpp.h.
#   (Hint: Use gcc -x c/objective-c/c++/objective-c++ -E.  It will
#   take time to check each header using gcc, so make it a switch.)

use strict;
use warnings;

use File::Basename;
use File::Spec;
use File::Temp qw(tempfile);
use Getopt::Long;

# Map of Xcode file types to file extensions.
my %typeExtensionMap = qw(
    sourcecode.c.c        .c
    sourcecode.c.h        .h
    sourcecode.c.objc     .m
    sourcecode.cpp.h      .h
    sourcecode.cpp.cpp    .cpp
    sourcecode.cpp.objcpp .mm
    sourcecode.exports    .exp
    sourcecode.javascript .js
    sourcecode.make       .make
    sourcecode.mig        .defs
    sourcecode.yacc       .y
);

# Map of file extensions to Xcode file types.
my %extensionTypeMap = map { $typeExtensionMap{$_} => $_ } keys %typeExtensionMap;
$extensionTypeMap{'.h'} = 'sourcecode.c.h'; # See TODO list.

my $shouldFixIssues = 0;
my $printWarnings = 1;
my $showHelp;

my $getOptionsResult = GetOptions(
    'f|fix'          => \$shouldFixIssues,
    'h|help'         => \$showHelp,
    'w|warnings!'    => \$printWarnings,
);

if (scalar(@ARGV) == 0 && !$showHelp) {
    print STDERR "ERROR: No Xcode project files (project.pbxproj) listed on command-line.\n";
    undef $getOptionsResult;
}

if (!$getOptionsResult || $showHelp) {
    print STDERR <<__END__;
Usage: @{[ basename($0) ]} [options] path/to/project.pbxproj [path/to/project.pbxproj ...]
  -f|--fix            fix mismatched types in Xcode project file
  -h|--help           show this help message
  -w|--[no-]warnings  show or suppress warnings (default: show warnings)
__END__
    exit 1;
}

for my $projectFile (@ARGV) {
    my $issuesFound = 0;
    my $issuesFixed = 0;

    if (basename($projectFile) =~ /\.xcodeproj$/) {
        $projectFile = File::Spec->catfile($projectFile, "project.pbxproj");
    }

    if (basename($projectFile) ne "project.pbxproj") {
        print STDERR "WARNING: Not an Xcode project file: $projectFile\n" if $printWarnings;
        next;
    }

    open(IN, "< $projectFile") || die "Could not open $projectFile: $!";

    my ($OUT, $tempFileName);
    if ($shouldFixIssues) {
        ($OUT, $tempFileName) = tempfile(
            basename($projectFile) . "-XXXXXXXX",
            DIR => dirname($projectFile),
            UNLINK => 0,
        );

        # Clean up temp file in case of die()
        $SIG{__DIE__} = sub {
            close(IN);
            close($OUT);
            unlink($tempFileName);
        };
    }

    # Fast-forward to "Begin PBXFileReference section".
    while (my $line = <IN>) {
        print $OUT $line if $shouldFixIssues;
        last if $line =~ m#^\Q/* Begin PBXFileReference section */\E$#;
    }

    while (my $line = <IN>) {
        if ($line =~ m#^\Q/* End PBXFileReference section */\E$#) {
            print $OUT $line if $shouldFixIssues;
            last;
        }

        if ($line =~ m#^\s*[A-Z0-9]{24} /\* (.+) \*/\s+=\s+\{.*\s+explicitFileType = (sourcecode[^;]*);.*\s+path = ([^;]+);.*\};$#) {
            my $fileName = $1;
            my $fileType = $2;
            my $filePath = $3;
            my (undef, undef, $fileExtension) = map { lc($_) } fileparse(basename($filePath), qr{\.[^.]+$});

            if (!exists $typeExtensionMap{$fileType}) {
                $issuesFound++;
                print STDERR "WARNING: Unknown file type '$fileType' for file '$filePath'.\n" if $printWarnings;
            } elsif ($typeExtensionMap{$fileType} ne $fileExtension) {
                $issuesFound++;
                print STDERR "WARNING: Incorrect file type '$fileType' for file '$filePath'.\n" if $printWarnings;
                $line =~ s/(\s+)explicitFileType( = )(sourcecode[^;]*);/$1lastKnownFileType$2$extensionTypeMap{$fileExtension};/;
                $issuesFixed++ if $shouldFixIssues;
            }
        }

        print $OUT $line if $shouldFixIssues;
    }

    # Output the rest of the file.
    print $OUT <IN> if $shouldFixIssues;

    close(IN);

    if ($shouldFixIssues) {
        close($OUT);

        unlink($projectFile) || die "Could not delete $projectFile: $!";
        rename($tempFileName, $projectFile) || die "Could not rename $tempFileName to $projectFile: $!";
    }

    if ($printWarnings) {
        printf STDERR "%s issues found for $projectFile.\n", ($issuesFound ? $issuesFound : "No");
        print STDERR "$issuesFixed issues fixed for $projectFile.\n" if $issuesFixed && $shouldFixIssues;
        print STDERR "NOTE: Open $projectFile in Xcode to let it have its way with the file.\n" if $issuesFixed;
        print STDERR "\n";
    }
}

exit 0;
