#!/bin/sh

FORCE="YES"

XCODEBUILD=/Developer/usr/bin/xcodebuild
BUILDROOT="$1"

EXTRACOPY=( \
    /usr/lib/dyld \
    /usr/share/icu \
    /Developer/Private \
    /Developer/Tools \
    /usr/bin/xcodebuild \
    /usr/bin/xcode-select \
    /Developer/Library/version.plist \
    /Developer/usr/bin/xcodebuild)
    
BINSYMLINKS=( \
    cc \
    dsymutil \
    gcc \
    gcc-4.0 \
    gcc-4.2 \
    gcov \
    gcov-4.0 \
    gcov-4.2 \
    g++ \
    g++-4.0 \
    g++-4.2 \
    libtool \
    mig \
    strip \
    yacc)
    

JAMFILES="/Developer/Makefiles/pbx_jamfiles"
#XCODERESOURCES="/Developer/Library/PrivateFrameworks/DevToolsCore.framework/Versions/A/Resources/"

RPATH=/Developer/Library/PrivateFrameworks

if [ -z "$BUILDROOT" ]; then
    echo "Usage: $0 <BuildRoot>" 1>&2
    exit 1
fi

mkdir -p "$BUILDROOT"

###
### Symlink opensource binaries used by Xcode to /usr/bin
###  so the opensource-built binary can be used instead
###  of the one that ships with Xcode
###
SymlinkBinaries() {
    echo "Creating symlinks for binaries ..."
    BIN_DIR="$BUILDROOT/XCD/loper/usr/bin/"
    mkdir -p $BIN_DIR
    pushd $BIN_DIR > /dev/null
    
    for B in "${BINSYMLINKS[@]}"; do
	ln -s "/usr/bin/$B" "$B"
    done

    popd > /dev/null
}

###
### Load opensource binaries if they dont exist so we can symlink to them
###  
LoadBinaries() {
    echo "Loading binaries ..."
    if [ ! -f "$BUILDROOT/usr/bin/gcc" ]; then
	darwinbuild -load gcc
    fi
    if [ ! -f "$BUILDROOT/usr/bin/gcc-4.2" ]; then
	darwinbuild -load gcc_42
    fi
}

###
### Recurse through frameworks and libraries looking for dependencies
###
RecurseLibs() {
	echo $1 >> /tmp/installXcode.seen.$$
	otool -L $1 | tail -n +2 | awk '{ print $1 }' > /tmp/installXcode.tmplibs.$$
	sed -e s,@rpath,${RPATH}, < /tmp/installXcode.tmplibs.$$ > /tmp/installXcode.outlibs.$$
	cat /tmp/installXcode.outlibs.$$ >> /tmp/installXcode.libs.$$
	cat /tmp/installXcode.outlibs.$$ | while read X; do
		if ! grep -q "^$X\$" /tmp/installXcode.seen.$$ ; then
			RecurseLibs $X
		fi
	done
}

RemoveTemps() {
	rm -f /tmp/installXcode.libs.$$
	rm -f /tmp/installXcode.outlibs.$$
	rm -f /tmp/installXcode.seen.$$
	rm -f /tmp/installXcode.tmplibs.$$
	rm -f /tmp/installXcode.tmpfiles.$$
	rm -f /tmp/installXcode.files.$$
}

AppendExtraFiles() {
    for X in "${EXTRACOPY[@]}"; do
	echo "$X" >> /tmp/installXcode.libs.$$
    done
}

TransformLibs() {
#    set -x
    while read X; do
	NEWX=$(echo $X | sed -n 's/\(.*\.framework\).*/\1/p')
	if [ -n "$NEWX" ]; then
	    # if we're copying a framework binary, copy the entire bundle
	    echo "$NEWX"
	    continue
	fi

	NEWX=$(echo $X | sed -n 's/\([^.]*\)\..*dylib$/\1/p')
	if [ -n "$NEWX" ]; then
	    # if we're copying a dylib, copy associate symlinks and stuff
	    for Y in "$NEWX"*.dylib; do
		echo "$Y"
	    done
	    continue
	fi

	echo "$X"
    done
#    set +x
}

GenerateFileNames() {
    cat /tmp/installXcode.libs.$$ | sort -u | TransformLibs | sort -u | while read X; do
	# echo adding children for "$X"

	# first mkdir parent directories
	PARENT=$(dirname "$X")
	while [ "$PARENT" != "/" -a "$PARENT" != "." ]; do
	    echo ".$PARENT" >> /tmp/installXcode.tmpfiles.$$
	    PARENT=$(dirname "$PARENT")
	done
	find ".$X" \! \( -name \*_debug\* -o -name \*_profile\* -o -path \*/Headers\* -o -path \*/PrivateHeaders\* -o -path \*.dict\* \) >> /tmp/installXcode.tmpfiles.$$
    done
    sort -u /tmp/installXcode.tmpfiles.$$ > /tmp/installXcode.files.$$
}

CopyFiles() {
#    VERBOSECPIO="v"
    VERBOSECPIO=""
    echo "Copying Xcode and dependencies ..."

    # copy files and use sed to rewrite paths during copy
    cpio -o -c < /tmp/installXcode.files.$$ | \
	sed -e 's,/System,/XCD/SY,g' \
	-e 's,CoreServices/XCD/SY,CoreServices/System,g' \
	-e 's,Resources/XCD/SY,Resources/System,g' \
	-e 's,/usr/lib,/XCD/lib,g' \
	-e 's,/usr/share/icu,/XCD/share/icu,g' \
        -e 's,@rpath,/XCD/R,g' \
	-e 's,/Developer,/XCD/loper,g' \
	-e 's,platform/XCD/loper,platform/Developer,g' | \
    (cd "$BUILDROOT"; cpio -ium${VERBOSECPIO}d )

    echo "Symlinking for RPATH ..."
    # symlink R to @rpath so we can replace uses of @rpath
    pushd "$BUILDROOT/XCD" > /dev/null
    ln -s loper/Library/PrivateFrameworks R
    popd > /dev/null

    echo "Copying Jamfiles ..."
    find ".$JAMFILES" | cpio -o -c | \
        sed -e 's,$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks,/XCD/SY///////Library/PrivateFrameworks,g' \
        -e 's,/Developer/Makefiles/pbx_jamfiles,/XCD/loper/Makefiles/pbx_jamfiles,g' \
        -e 's,/Developer/Library/PrivateFrameworks/DevToolsCore.framework,/XCD/loper/Library/PrivateFrameworks/DevToolsCore.framework,g' | \
    (cd "$BUILDROOT"; cpio -ium${VERBOSECPIO}d )


    echo "Copying CoreServices ..."
    find ./System/Library/CoreServices/System*.{plist,bundle} \
	 ./System/Library/CoreServices/CoreTypes.bundle/ \
	| cpio -o -c | \
	sed -e 's,/System,/XCD/SY,g' \
	-e 's,CoreServices/XCD/SY,CoreServices/System,g' \
	-e 's,Resources/XCD/SY,Resources/System,g' \
	-e 's,/usr/lib,/XCD/lib,g' \
	-e 's,/usr/share/icu,/XCD/share/icu,g' \
        -e 's,@rpath,/XCD/R,g' \
	-e 's,/Developer,/XCD/loper,g' \
	-e 's,platform/XCD/loper,platform/Developer,g' | \
    (cd "$BUILDROOT"; cpio -ium${VERBOSECPIO}d )

    # copy xcode support files such as plugins
    #   but do not copy svn plugins since they are unecessary
    echo "Copying Xcode library support files ..."
    find "./Developer/Library/Xcode/" \! -ipath '*subversion*' \
	| cpio -o -c | \
	sed -e 's,/System,/XCD/SY,g' \
	-e 's,CoreServices/XCD/SY,CoreServices/System,g' \
	-e 's,Resources/XCD/SY,Resources/System,g' \
	-e 's,/usr/lib,/XCD/lib,g' \
	-e 's,/usr/share/icu,/XCD/share/icu,g' \
        -e 's,@rpath,/XCD/R,g' \
	-e 's,/Developer,/XCD/loper,g' \
	-e 's,platform/XCD/loper,platform/Developer,g' | \
    (cd "$BUILDROOT"; cpio -ium${VERBOSECPIO}d )           

    # Platform
    echo "Copying Mac OS X Platform ..."
    find "./Developer/Platforms/MacOSX.platform" | cpio -o -c | \
        sed -e 's,/System,/XCD/SY,g' \
        -e 's,CoreServices/XCD/SY,CoreServices/System,g' \
        -e 's,Resources/XCD/SY,Resources/System,g' \
        -e 's,/usr/lib,/XCD/lib,g' \
        -e 's,/usr/share/icu,/XCD/share/icu,g' \
        -e 's,@rpath,/XCD/R,g' \
        -e 's,/Developer,/XCD/loper,g' \
        -e 's,platform/XCD/loper,platform/Developer,g' | \
    (cd "$BUILDROOT"; cpio -ium${VERBOSECPIO}d )

}



###
### Find all the framework and library dependencies of Xcode build
### For frameworks, copy over all supporting files.
###

pushd / > /dev/null

RemoveTemps
touch /tmp/installXcode.seen.$$
echo Analyzing Xcode dependencies ...
RecurseLibs $XCODEBUILD
AppendExtraFiles
GenerateFileNames
CopyFiles
LoadBinaries
SymlinkBinaries

popd > /dev/null

#RemoveTemps

echo "Completed Xcode installation!"
