#!/usr/bin/python

# Copyright (C) 2009, 2015 Apple Inc.  All rights reserved.
# Copyright (C) 2012 Google 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
import os
import shutil
import subprocess
import sys
import zipfile

_configurationBuildDirectory = None
_topLevelBuildDirectory = None


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")
        return 1
    if not options.configuration:
        parser.error("Configuration is required")
        return 1
    if action not in ('archive', 'extract'):
        parser.error("Action is required")
        return 1

    genericPlatform = options.platform.split('-', 1)[0]
    determineWebKitBuildDirectories(genericPlatform, options.platform, options.configuration)
    if not _topLevelBuildDirectory:
        print >> sys.stderr, 'Could not determine top-level build directory'
        return 1
    if not _configurationBuildDirectory:
        print >> sys.stderr, 'Could not determine configuration-specific build directory'
        return 1

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


def webkitBuildDirectoryForConfigurationAndPlatform(configuration, platform, fullPlatform='', returnTopLevelDirectory=False):
    if fullPlatform.startswith('ios-simulator'):
        platform = 'ios-simulator'
    elif platform == 'ios':
        platform = 'device'
    command = ['perl', os.path.join(os.path.dirname(__file__), '..', 'Scripts', 'webkit-build-directory'), '--' + platform, '--' + configuration]
    if returnTopLevelDirectory:
        command += ['--top-level']
    else:
        command += ['--configuration']
    return subprocess.Popen(command, stdout=subprocess.PIPE).communicate()[0].strip()


def determineWebKitBuildDirectories(platform, fullPlatform, configuration):
    global _configurationBuildDirectory
    global _topLevelBuildDirectory
    _configurationBuildDirectory = webkitBuildDirectoryForConfigurationAndPlatform(configuration, platform, fullPlatform)
    _topLevelBuildDirectory = webkitBuildDirectoryForConfigurationAndPlatform(configuration, platform, fullPlatform, returnTopLevelDirectory=True)
    return _topLevelBuildDirectory


def removeDirectoryIfExists(thinDirectory):
    if os.path.isdir(thinDirectory):
        shutil.rmtree(thinDirectory)


def copyBuildFiles(source, destination, patterns):
    shutil.copytree(source, destination, ignore=shutil.ignore_patterns(*patterns))


def createZipManually(directoryToZip, archiveFile):
    archiveZip = zipfile.ZipFile(archiveFile, "w")

    for path, dirNames, fileNames in os.walk(directoryToZip):
        relativePath = os.path.relpath(path, directoryToZip)
        for fileName in fileNames:
            archiveZip.write(os.path.join(path, fileName), os.path.join(relativePath, fileName))

    archiveZip.close()


def createZip(directoryToZip, configuration, embedParentDirectoryNameOnDarwin=False):
    archiveDir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "WebKitBuild"))
    archiveFile = os.path.join(archiveDir, configuration + ".zip")

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

    if sys.platform == 'darwin':
        command = ['ditto', '-c', '-k', '--sequesterRsrc']
        if embedParentDirectoryNameOnDarwin:
            command += ['--keepParent']
        command += [directoryToZip, archiveFile]
        return subprocess.call(command)
    elif sys.platform == 'cygwin':
        return subprocess.call(["zip", "-r", archiveFile, "bin32"], cwd=directoryToZip)
    elif sys.platform == 'win32':
        createZipManually(directoryToZip, archiveFile)
        return 0
    elif sys.platform.startswith('linux'):
        return subprocess.call(["zip", "-y", "-r", archiveFile, "."], cwd=directoryToZip)


def dirContainsdwo(directory):
    sourcedir = os.path.join(_configurationBuildDirectory, directory)
    for root, dirs, files in os.walk(sourcedir, topdown=False):
        for name in files:
            if name.endswith(".dwo"):
                return True
    return False


def archiveBuiltProduct(configuration, platform, fullPlatform):
    assert platform in ('mac', 'win', 'gtk', 'efl', 'ios')

    if fullPlatform.startswith('ios-simulator'):
        # We need to include in the archive the Mac tool, LayoutTestRelay, to run layout tests in the iOS simulator.
        combinedDirectory = os.path.join(_topLevelBuildDirectory, 'combined-mac-and-ios')
        removeDirectoryIfExists(combinedDirectory)
        os.makedirs(combinedDirectory)

        if subprocess.call(['/bin/cp', '-pR', _configurationBuildDirectory, combinedDirectory]):
            return 1

        macBuildDirectory = webkitBuildDirectoryForConfigurationAndPlatform(configuration, 'mac')
        destinationDirectory = os.path.join(combinedDirectory, os.path.relpath(macBuildDirectory, _topLevelBuildDirectory))
        os.makedirs(destinationDirectory)
        for filename in ['LayoutTestRelay', 'LayoutTestRelay.dSYM']:
            sourceFile = os.path.join(macBuildDirectory, filename)
            if not os.path.exists(sourceFile):
                continue
            if subprocess.call(['/bin/cp', '-pR', sourceFile, destinationDirectory]):
                return 1

        if createZip(combinedDirectory, configuration):
            return 1
        shutil.rmtree(combinedDirectory)
    elif platform in ('mac', 'ios'):
        return createZip(_configurationBuildDirectory, configuration, embedParentDirectoryNameOnDarwin=True)
    elif platform == 'win':
        # FIXME: We shouldn't hardcode the assumption of a 32-bit build. See <https://bugs.webkit.org/show_bug.cgi?id=149715>.
        binDirectory = os.path.join(_configurationBuildDirectory, 'bin32')
        thinDirectory = os.path.join(_configurationBuildDirectory, 'thin')
        thinBinDirectory = os.path.join(thinDirectory, "bin32")

        removeDirectoryIfExists(thinDirectory)
        copyBuildFiles(binDirectory, thinBinDirectory, ['*.ilk'])
        if createZip(thinDirectory, configuration):
            return 1

        shutil.rmtree(thinDirectory)

    elif platform == 'gtk' or platform == 'efl':
        thinDirectory = os.path.join(_configurationBuildDirectory, 'thin')

        removeDirectoryIfExists(thinDirectory)
        os.mkdir(thinDirectory)

        neededDirectories = ["bin", "lib"]

        # When debug fission is enabled the directories below contain dwo files
        # with the debug information needed to generate backtraces with GDB.
        for objectDir in ["Tools", "Source"]:
            if dirContainsdwo(objectDir):
                neededDirectories.append(objectDir)

        for dirname in neededDirectories:
            fromDir = os.path.join(_configurationBuildDirectory, dirname, '.')
            toDir = os.path.join(thinDirectory, dirname)
            os.makedirs(toDir)
            if subprocess.call('cp -R %s %s' % (fromDir, toDir), shell=True):
                return 1

        for root, dirs, files in os.walk(thinDirectory, topdown=False):
            for name in files:
                if name.endswith(".o"):
                    os.remove(os.path.join(root, name))

        if createZip(thinDirectory, configuration):
            return 1

def unzipArchive(directoryToExtractTo, configuration):
    archiveDir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "WebKitBuild"))
    assert os.path.isdir(archiveDir)
    archiveFile = os.path.join(archiveDir, configuration + ".zip")

    if sys.platform == 'darwin':
        if subprocess.call(["ditto", "-x", "-k", archiveFile, directoryToExtractTo]):
            return 1
    elif sys.platform == 'cygwin' or sys.platform.startswith('linux'):
        if subprocess.call(["unzip", "-o", archiveFile], cwd=directoryToExtractTo):
            return 1
    elif sys.platform == 'win32':
        archive = zipfile.ZipFile(archiveFile, "r")
        archive.extractall(directoryToExtractTo)
        archive.close()

    os.unlink(archiveFile)


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

    archiveFile = os.path.join(_topLevelBuildDirectory, configuration + '.zip')

    removeDirectoryIfExists(_configurationBuildDirectory)
    os.makedirs(_configurationBuildDirectory)

    if platform in ('mac', 'ios'):
        return unzipArchive(_topLevelBuildDirectory, configuration)
    elif platform == 'win' or platform == 'gtk' or platform == 'efl':
        print 'Extracting', _configurationBuildDirectory
        return unzipArchive(_configurationBuildDirectory, configuration)


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