#!/usr/bin/env 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 errno
import optparse
import os
import shutil
import subprocess
import sys
import zipfile

_configurationBuildDirectory = None
_topLevelBuildDirectory = None
_hostBuildDirectory = None

PATH_TO_LAUNCHER = './Tools/WebKitArchiveSupport/run-webkit-archive'
PATH_TO_README = './Tools/WebKitArchiveSupport/README'

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")
    parser.add_option("--minify", action="store_true", dest="minify", default=False,
                      help="Create a minified archive by removing files that are not necessary for running applications against the built product, at the cost of complicating debugging.")
                      
    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, options.minify)
    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
    global _hostBuildDirectory
    _configurationBuildDirectory = webkitBuildDirectoryForConfigurationAndPlatform(configuration, platform, fullPlatform)
    _topLevelBuildDirectory = webkitBuildDirectoryForConfigurationAndPlatform(configuration, platform, fullPlatform, returnTopLevelDirectory=True)
    if platform == 'ios':
        _hostBuildDirectory = webkitBuildDirectoryForConfigurationAndPlatform(configuration, 'mac')
    else:
        _hostBuildDirectory = _configurationBuildDirectory
    
    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 createZipFromList(listToZip, configuration, excludePattern=None):
    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 != errno.ENOENT:
            raise

    if sys.platform.startswith('linux'):
        zipCommand = ['zip', '-y', '-r', archiveFile] + listToZip
        if excludePattern:
            zipCommand += ['-x', excludePattern]
        return subprocess.call(zipCommand, cwd=_configurationBuildDirectory)

    raise NotImplementedError('Unsupported platform: {platform}'.format(platform=sys.platform))


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 addFilesToArchive(archiveFile, pathToLauncher, pathToReadme):
    command = ['/usr/bin/zip', '-j', archiveFile, pathToLauncher, pathToReadme]
    return subprocess.call(command)

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

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

    if sys.platform == 'darwin':
        command = ['ditto', '-c', '-k', '--sequesterRsrc']
        if embedParentDirectoryNameOnDarwin:
            command += ['--keepParent']
        command += [directoryToZip, archiveFile]
        return subprocess.call(command) or addFilesToArchive(archiveFile, PATH_TO_LAUNCHER, PATH_TO_README) 
    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 minifyDirectory(platform, directory):
    if platform == 'mac' or platform == 'ios':
        dir_patterns = ('.dSYM', 'DerivedSources')
        file_patterns = ('.a',)
        for root, dirs, files in os.walk(directory):
            if any(root.endswith(pattern) for pattern in dir_patterns):
                print 'Removing: {}'.format(root)
                shutil.rmtree(root)
            for name in files:
                if any(name.endswith(pattern) for pattern in file_patterns):
                    print 'Removing: {}'.format(os.path.join(root, name))
                    os.remove(os.path.join(root, name))


def archiveBuiltProduct(configuration, platform, fullPlatform, minify=False):
    assert platform in ('mac', 'win', 'gtk', 'ios', 'wpe')

    if platform == 'ios':
        combinedDirectory = os.path.join(_topLevelBuildDirectory, 'combined-mac-and-ios')
        removeDirectoryIfExists(combinedDirectory)
        os.makedirs(combinedDirectory)
        if minify:
            minifyDirectory(platform, _configurationBuildDirectory)
            minifyDirectory(platform, _hostBuildDirectory)
        if subprocess.call(['/bin/cp', '-pR', _configurationBuildDirectory, combinedDirectory]):
            return 1
        if subprocess.call(['/bin/cp', '-pR', _hostBuildDirectory, combinedDirectory]):
            return 1

        return createZip(combinedDirectory, configuration, minify=minify)
    elif platform == 'mac':
        if minify:
            minifyDirectory(platform, _configurationBuildDirectory)
        return createZip(_configurationBuildDirectory, configuration, embedParentDirectoryNameOnDarwin=True, minify=minify)
    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 == 'wpe':
        # On GTK+/WPE we don't need the intermediate step of creating a thinDirectory
        # to be compressed in a ZIP file, because we can create the ZIP directly.
        # This is faster and requires less disk resources.
        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)

        if createZipFromList(neededDirectories, configuration, excludePattern='*.o'):
            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', 'ios', 'wpe')

    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 == 'wpe':
        print 'Extracting', _configurationBuildDirectory
        return unzipArchive(_configurationBuildDirectory, configuration)


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