#!/usr/bin/python

# Copyright (C) 2009 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.

import optparse, os, shutil, subprocess, sys

buildDirectory = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "WebKitBuild"))

def main():
    parser = optparse.OptionParser("usage: %prog [options] [action]")
    parser.add_option("--platform", dest="platform")
    parser.add_option("--debug", action="store_const", const="debug", dest="configuration")
    parser.add_option("--release", action="store_const", const="release", dest="configuration")

    options, (action, ) = parser.parse_args()
    if not options.platform:
        parser.error("Platform is required")
    if not options.configuration:
        parser.error("Configuration is required")
    if action not in ('archive', 'extract'):
        parser.error("Action is required")

    if action == 'archive':
        archiveBuiltProduct(options.configuration, options.platform)
    else:
        extractBuiltProduct(options.configuration, options.platform)


def archiveBuiltProduct(configuration, platform):
    assert platform in ('mac', 'win')

    archiveFile = os.path.join(buildDirectory, configuration + ".zip")

    try:
        os.unlink(archiveFile)
    except OSError, e:
        if e.errno != 2:
            raise

    if platform == 'mac':
        configurationBuildDirectory = os.path.join(buildDirectory, configuration.title())
        return subprocess.call(["ditto", "-c", "-k", "--keepParent", "--sequesterRsrc", configurationBuildDirectory, archiveFile])
    elif platform == 'win':
        binDirectory = os.path.join(buildDirectory, "bin")
        thinDirectory = os.path.join(buildDirectory, "thin")
        thinBinDirectory = os.path.join(thinDirectory, "bin")

        if os.path.isdir(thinDirectory):
            shutil.rmtree(thinDirectory)
        os.mkdir(thinDirectory)

        if subprocess.call(["cp", "-R", binDirectory, thinBinDirectory]):
            return 1

        if subprocess.call("rm -f %s" % os.path.join(thinBinDirectory, "*.ilk"), shell=True):
            return 1

        if subprocess.call(["zip", "-r", archiveFile, "bin"], cwd=thinDirectory):
            return 1

        shutil.rmtree(thinDirectory)

def extractBuiltProduct(configuration, platform):
    assert platform in ('mac', 'win')

    archiveFile = os.path.join(buildDirectory, configuration + ".zip")

    if platform == 'mac':
        configurationBuildDirectory = os.path.join(buildDirectory, configuration.title())

        if os.path.isdir(configurationBuildDirectory):
            shutil.rmtree(configurationBuildDirectory)

        if subprocess.call(["ditto", "-x", "-k", archiveFile, buildDirectory]):
            return 1
        os.unlink(archiveFile)

    elif platform == 'win':
        binDirectory = os.path.join(buildDirectory, "bin")
        if os.path.isdir(binDirectory):
            shutil.rmtree(binDirectory)

        os.mkdir(binDirectory)

        safariPath = subprocess.Popen('cygpath -w "$PROGRAMFILES"/Safari',
                                      shell=True, stdout=subprocess.PIPE).communicate()[0].strip()

        if subprocess.call('cp -R "%s"/*.dll "%s"/*.resources %s' % (safariPath, safariPath, binDirectory), shell=True):
            return 1

        if subprocess.call(["unzip", "-o", archiveFile], cwd=buildDirectory):
            return 1

        

if __name__ == '__main__':
    sys.exit(main())
