#! /usr/bin/env python

# Copyright (C) 2009 Kevin Ollivier  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 COMPUTER, INC. ``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 COMPUTER, INC. OR
# 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. 
#
# WebCore build script for the waf build system

import glob
import os
import subprocess

import Options

from settings import *
import wxpresets

import TaskGen
from TaskGen import taskgen, feature, after
import Task, ccroot

def clean_derived_sources(ds_cmd):
    # the below command does not produce the desired output under Cygwin, so for now,
    # disable this under Windows.
    if building_on_win32:
        return
        
    cmd = ds_cmd + " -qp | grep -v '^# ' | grep -v '^[[:space:]]' | grep --only-matching '^.*:'"
    output = subprocess.check_output(cmd, shell=True)
    
    targets = []
    lines = output.split("\n")
    for line in lines:
        line = line.replace(":", "")
        base = os.path.splitext(os.path.basename(line))[0]
        if not base in targets:
            targets.append(base)
            if base == "UserAgentsStyleSheet":
                targets.append("UserAgentsStyleSheetData")
    
    # we're in the DerivedSources directory when this command is run.
    ds_files = glob.glob("*.*")
    for ds_file in ds_files:
        filename = os.path.basename(ds_file)
        basename = os.path.splitext(filename)[0]
        # For now, just remove JS*.h/.cpp and WebDOM*.h/.cpp when there are no longer targets
        # for them. Other targets may generate supplemental files so we can't reliably clean them.
        if not basename in targets and (basename.startswith("JS") or basename.startswith("WebDOM")):
            print "INFO: %s is no longer generated but present in generated files directory. Removing." % filename
            os.remove(ds_file)
    
def generate_webcore_derived_sources(conf):
    # build the derived sources
    derived_sources_dir = os.path.join(webcore_dir, 'DerivedSources')
    wc_dir = webcore_dir
    if building_on_win32:
        wc_dir = get_output('cygpath --unix "%s"' % wc_dir)
    if not os.path.exists(derived_sources_dir):
        os.mkdir(derived_sources_dir)

    olddir = os.getcwd()
    os.chdir(derived_sources_dir)
    
    # DerivedSources.make expects Cygwin (i.e. Unix-style) python, so use that instead.
    if building_on_win32:
        oldpath = os.environ["PATH"]
        os.environ["PATH"] = "/usr/bin" + os.pathsep + os.environ["PATH"]
    command = 'make -f %s/DerivedSources.make WebCore=%s SOURCE_ROOT=%s all FEATURE_DEFINES="%s"' % (wc_dir, wc_dir, wc_dir, conf.env["FEATURE_DEFINES"])
    clean_derived_sources(command)
    os.system(command)
    if building_on_win32:
        os.environ["PATH"] = oldpath
    
    os.chdir(olddir)

def generate_jscore_derived_sources(conf):
    # build the derived sources
    js_dir = jscore_dir
    if building_on_win32:
        js_dir = get_output('cygpath --unix "%s"' % js_dir)
    derived_sources_dir = os.path.join(jscore_dir, 'DerivedSources')
    if not os.path.exists(derived_sources_dir):
        os.mkdir(derived_sources_dir)

    olddir = os.getcwd()
    os.chdir(derived_sources_dir)

    # DerivedSources.make expects Cygwin (i.e. Unix-style) python, so use that instead.
    if building_on_win32:
        oldpath = os.environ["PATH"]
        os.environ["PATH"] = "/usr/bin" + os.pathsep + os.environ["PATH"]
    command = 'make -f %s/DerivedSources.make JavaScriptCore=%s BUILT_PRODUCTS_DIR=%s all FEATURE_DEFINES="%s"' % (js_dir, js_dir, js_dir, conf.env["FEATURE_DEFINES"])
    os.system(command)
    if building_on_win32:
        os.environ["PATH"] = oldpath
    os.chdir(olddir)

def set_options(opt):
    common_set_options(opt)

def configure(conf):
    common_configure(conf)
    generate_jscore_derived_sources(conf)
    generate_webcore_derived_sources(conf)
    if Options.options.port == "wx" and sys.platform.startswith('win'):
        graphics_dir = os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'graphics')
        # we used to copy these files into the graphics/wx directory due to 
        # both wx and win directories having FontPlatformData.h. That is no 
        # longer the case, so we remove the old files if they exist.
        for afile in ['UniscribeController.h', 'UniscribeController.cpp', 'GlyphPageTreeNodeCairoWin.cpp']:
            wx_copy = os.path.join(graphics_dir, 'wx', afile)
            if os.path.exists(wx_copy):
                os.remove(wx_copy)

    webcore_out_dir = os.path.join(output_dir, 'WebCore')
    if not os.path.exists(webcore_out_dir):
        os.makedirs(webcore_out_dir)
    shutil.copy('Source/WebCore/platform/mac/WebCoreSystemInterface.h', os.path.join(output_dir, 'WebCore', 'WebCoreSystemInterface.h'))
    jscore_out_dir = os.path.join(output_dir, 'JavaScriptCore')
    if not os.path.exists(jscore_out_dir):
        os.makedirs(jscore_out_dir)
    for api_file in glob.glob(os.path.join(jscore_dir, 'API/*.h')):
        shutil.copy(api_file, os.path.join(jscore_out_dir, os.path.basename(api_file)))

    if Options.options.port == "wx" and Options.options.wxpython:
        common_configure(conf)
        conf.check_tool('swig', tooldir='Source/WebKit/wx/bindings/python')
        conf.check_swig_version('1.3.29')

def build(bld):

    webcore_dirs = list(webcore_dirs_common)

    # auto-generate WebKitVersion.h if needed before we start the build.
    # Also, remove the file from the old location where we generated it before running
    wk_version_h = 'Source/WebCore/DerivedSources/WebKitVersion.h'
    if os.path.exists(wk_version_h):
        os.remove(wk_version_h)
    bld.new_task_gen(source = "Source/WebKit/mac/Configurations/Version.xcconfig",
                     target = wk_version_h,
                     rule = 'perl %s/Source/WebKit/scripts/generate-webkitversion.pl --outputDir=${TGT[0].dir(env)} --config ${SRC}' % wk_root)
    bld.add_group()

    if Options.options.port == "wx":
        webcore_dirs.extend(['Source/WebKit/wx', 'Source/WebKit/wx/WebKitSupport'])
    
    wk_includes = ['.',
                    os.path.join(wk_root, 'Source', 'WTF'),
                    os.path.join(wk_root, 'Source', 'WTF', 'wtf'),
                    os.path.join(wk_root, 'Source', 'JavaScriptCore'),
                    os.path.join(wk_root, 'Source', 'WebCore'),
                    os.path.join(wk_root, 'Source', 'WebCore', 'DerivedSources'),
                    os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'graphics', 'opentype'),
                    os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'image-decoders'),
                    os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'win'),
                    os.path.join(wk_root, 'Source', 'WebCore', 'workers'),
                    os.path.join(output_dir),
            ]
    
    if Options.options.port == "wx":
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebKit', 'wx'))
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'wx', 'wxcode'))
    
    if sys.platform.startswith("win"):
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'win'))
        wk_includes.append(os.path.join(wk_root, 'Source', 'WebCore', 'platform', 'graphics', 'win'))
    
    windows_deps = [
                    'lib/pthreadVC2.dll',
                    'bin/icuuc40.dll', 'bin/icudt40.dll', 'bin/icuin40.dll',
                    'bin/libcurl.dll', 'bin/libeay32.dll', 'bin/ssleay32.dll', 'bin/zlib1.dll',
                    'lib/sqlite3.dll', 'bin/libxml2.dll', 'bin/libxslt.dll', 'bin/iconv.dll',
                    ]
    
    webcore_sources = {}
    
    if Options.options.port == "wx":
        webcore_sources['wx'] = [
            'Source/WebCore/bindings/cpp/WebDOMEventTarget.cpp',
            'Source/WebCore/platform/KillRingNone.cpp',
            'Source/WebCore/platform/text/LocalizedDateNone.cpp',
            'Source/WebCore/platform/text/LocalizedNumberNone.cpp',
            'Source/WebCore/page/scrolling/ScrollingCoordinatorNone.cpp',
        ]  
    
        if building_on_win32:
            # make sure platform/wx comes after this so we get the right
            # FontPlatformData.h
            webcore_dirs.extend(['Source/WebCore/platform/wx/wxcode/win', 'Source/WebCore/plugins/win'])
            webcore_sources['wx-win'] = [
                   'Source/WebCore/platform/graphics/win/GlyphPageTreeNodeCairoWin.cpp',
                   'Source/WebCore/platform/graphics/win/TransformationMatrixWin.cpp',
                   'Source/WebCore/platform/graphics/win/UniscribeController.cpp',
                   'Source/WebCore/platform/ScrollAnimatorNone.cpp',
                   # wxTimer on Windows has a bug that causes it to eat crashes in callbacks
                   # so we need to use the Win port's implementation until the wx bug fix is
                   # widely available (it was fixed in 2.8.10).
                   'Source/WebCore/platform/win/SharedTimerWin.cpp',
                   'Source/WebCore/platform/win/SystemInfo.cpp',
                   'Source/WebCore/platform/win/WebCoreInstanceHandle.cpp',
                   # Use the Windows plugin architecture
                   #'Source/WebCore/plugins/win/PluginDataWin.cpp',
                   'Source/WebCore/plugins/win/PluginDatabaseWin.cpp',
                   'Source/WebCore/plugins/win/PluginMessageThrottlerWin.cpp',
                   'Source/WebCore/plugins/win/PluginPackageWin.cpp',
                   'Source/WebCore/plugins/win/PluginViewWin.cpp',
            ]
            if Options.options.cairo:
                webcore_dirs.append('Source/WebCore/platform/wx/wxcode/cairo')
            else:
                webcore_dirs.append('Source/WebCore/platform/wx/wxcode/gdiplus')
        elif sys.platform.startswith('darwin'):
            webcore_dirs.append('Source/WebCore/plugins/mac')
            webcore_dirs.append('Source/WebCore/platform/wx/wxcode/mac/carbon')
            webcore_dirs.append('Source/WebCore/platform/text/mac')
            webcore_sources['wx-mac'] = [
                   'Source/WebCore/platform/mac/PurgeableBufferMac.cpp',
                   'Source/WebCore/platform/mac/WebCoreNSStringExtras.mm',
                   'Source/WebCore/platform/mac/WebCoreSystemInterface.mm',
                   'Source/WebCore/platform/graphics/cg/FloatSizeCG.cpp',
                   'Source/WebCore/platform/graphics/mac/ComplexTextController.cpp',
                   'Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm',
                   'Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp',
                   'Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp',
                   'Source/WebCore/platform/graphics/wx/FontPlatformDataWxMac.mm',
                   'Source/WebCore/platform/wx/wxcode/mac/carbon/fontprops.mm',
                   'Source/WebCore/plugins/mac/PluginPackageMac.cpp',
                   'Source/WebCore/plugins/mac/PluginViewMac.mm'
            ]
        else:
            webcore_sources['wx-gtk'] = [
                   'Source/WebCore/plugins/PluginViewNone.cpp',
                   'Source/WebCore/plugins/PluginPackageNone.cpp'
            ]
            webcore_dirs.append('Source/WebCore/platform/wx/wxcode/gtk')
            webcore_dirs.append('Source/WebCore/platform/wx/wxcode/cairo')
        

    import TaskGen

    bld.add_subdirs('Source/JavaScriptCore')

    if sys.platform.startswith('darwin'):
        TaskGen.task_gen.mappings['.mm'] = TaskGen.task_gen.mappings['.cxx']
        TaskGen.task_gen.mappings['.m'] = TaskGen.task_gen.mappings['.cxx']

    features = [Options.options.port.lower()]
    thisport = Options.options.port
    
    exclude_patterns = ['*AllInOne.cpp', '*None.cpp',]

    if sys.platform.startswith('darwin'):
        features.append('cf')

    # exclude the filename patterns for all other ports.
    exclude_patterns.extend(get_port_excludes(Options.options.port))
            
    if Options.options.port == 'wx':
        features.append('curl')
        exclude_patterns.extend(['*CFNet.cpp', 'test*bindings.*', "WebDOMCanvas*.cpp", "WebDOMSVG*.cpp"])
        
    full_dirs = get_dirs_for_features(wk_root, features=features, dirs=webcore_dirs)

    # make sure we don't use the CF networking engine
    if Options.options.port == 'wx' and sys.platform.startswith('darwin'):
        full_dirs.remove('Source/WebCore/platform/network/cf')
        
    jscore_dir = os.path.join(wk_root, 'Source', 'JavaScriptCore')
    for item in os.listdir(jscore_dir):
        fullpath = os.path.join(jscore_dir, item)
        if os.path.isdir(fullpath) and not item == "os-win32" and not item == 'icu':
            wk_includes.append(fullpath)

    wk_includes.append('Source')
    wk_includes.append(os.path.join(jscore_dir, 'collector', 'handles'))
    wk_includes += common_includes + full_dirs
    if sys.platform.startswith('darwin'):
        wk_includes.append(os.path.join(webcore_dir, 'icu'))

    cxxflags = []
    if building_on_win32:
        cxxflags.append('/FIWebCorePrefix.h')
        # FIXME: We do this because in waf, local include dirs take precedence
        # over global ones. This makes sense, but because unicode/utf8.h is both
        # an ICU header name and a WebKit header name (in Source/JavaScriptCore/wtf)
        # we have to make sure <unicode/utf8.h> picks up the ICU one first.
        global msvclibs_dir
        wk_includes.append(os.path.join(msvclibs_dir, 'include'))
        wk_includes.append('Source/WebCore/platform/graphics/win')
    else:
        cxxflags.extend(['-include', 'WebCorePrefix.h'])

    webcore = bld.new_task_gen(
        features = 'cc cxx cshlib',
        includes = ' '.join(wk_includes),
        source = ' '.join(flattenSources(webcore_sources.values())),
        cxxflags = cxxflags,
        defines = ['WXMAKINGDLL_WEBKIT', 'BUILDING_WebCore'],
        libpath = [output_dir],
        target = 'wxwebkit',
        uselib = 'WX ICU XML XSLT CURL SQLITE3 WKINTERFACE ' + get_config(),
        uselib_local = 'jscore',
        install_path = output_dir,
        )
        
    excludes = []
    
    if Options.options.port == 'wx':
        excludes = get_excludes(webcore_dir, exclude_patterns)
        excludes.extend(['UserStyleSheetLoader.cpp', 'RenderMediaControls.cpp'])

        # intermediate sources
        excludes.append('DocTypeStrings.cpp')
        excludes.append('HTMLEntityNames.cpp')

        # Qt specific file in common sources
        excludes.append('ContextShadow.cpp')

        # FIXME: these require headers that I can't seem to find in trunk.
        # Investigate how to resolve these issues.
        excludes.append('JSAbstractView.cpp')
        excludes.append('JSIntentConstructor.cpp')
        excludes.append('JSPositionCallback.cpp')
        excludes.append('JSInspectorController.cpp')
        
        # The bindings generator seems to think these are ref-counted, while they aren't in trunk.
        excludes.append('JSElementTimeControl.cpp')
        excludes.append('JSSVGAnimatedPathData.cpp')
        excludes.append('JSSVGAnimatedPoints.cpp')
        excludes.append('JSSVGExternalResourcesRequired.cpp')
        excludes.append('JSSVGFilterPrimitiveStandardAttributes.cpp')
        excludes.append('JSSVGLocatable.cpp')
        excludes.append('JSSVGStyleTable.cpp')
        excludes.append('JSSVGTests.cpp')
        
        # These are files that expect methods not in the base C++ class, usually XYZAnimated methods.
        excludes.append('JSSVGFitToViewBox.cpp')
        excludes.append('JSSVGLangSpace.cpp')
        excludes.append('JSSVGTransformable.cpp')
        excludes.append('JSSVGURIReference.cpp')
        
        # These are C++ DOM Bindings that won't compile because they look for things not in trunk.
        excludes.append('WebDOMEventTarget.cpp')
        excludes.append('WebDOMAbstractView.cpp')
        excludes.append('WebDOMBlobBuilder.cpp')
        excludes.append('WebDOMEventListenerCustom.cpp')
        excludes.append('WebDOMElementTimeControl.cpp')
        excludes.append('WebDOMImageData.cpp')
        excludes.append('WebDOMInspectorBackend.cpp')
        excludes.append('WebDOMScriptProfile.cpp')
        excludes.append('WebDOMScriptProfileNode.cpp')
        excludes.append('WebNativeEventListener.cpp')
        
        # FIXME: It appears these are no longer needed by any port, once this is confirmed,
        # we should remove these sources from the tree.
        excludes.append('WebDOMDOMWindowCustom.cpp')
        excludes.append('WebDOMHTMLOptionsCollectionCustom.cpp')
        excludes.append('WebDOMNodeCustom.cpp')
        excludes.append('WebDOMHTMLDocumentCustom.cpp')
        excludes.append('WebDOMHTMLCollectionCustom.cpp')
        excludes.append('WebNativeNodeFilterCondition.cpp')
        excludes.append('WebDOMNodeFilterCustom.cpp')
        
        # don't compile for now until we figure out the issue with using DOMStringList
        excludes.append('WebDOMInternals.cpp')
        
        # this file is unused by any port, not sure why it was
        # left in the tree
        excludes.append('GeneratedImage.cpp')
        
        # features we don't build / use
        excludes.append('JSNavigatorCustom.cpp')
        excludes.append('WebGLContextEvent.cpp')
        excludes.append('FileSystemPOSIX.cpp')
        excludes.append('LocaleICU.cpp')
        excludes.append('LocalizedDateICU.cpp')
        excludes.append('PlatformGestureRecognizer.cpp')
        excludes.append('SharedBufferPOSIX.cpp')
        excludes.append('TouchAdjustment.cpp')
        excludes.append('DNSResolveQueue.cpp')
        excludes.append('WebDOMRadioNodeList.cpp')
        
        # These files appear not to build with older versions of ICU
        excludes.append('LocalizedNumberICU.cpp')
        excludes.append('LocaleToScriptMappingICU.cpp')
        
        if building_on_win32:
            excludes.append('SharedTimerWx.cpp')
            excludes.append('RenderThemeWin.cpp')
            excludes.append('KeyEventWin.cpp')
            
        if building_on_win32 or sys.platform.startswith('darwin'):
            excludes.append('GlyphMapWx.cpp')
        excludes.append('AuthenticationCF.cpp')
        excludes.append('LoaderRunLoopCF.cpp')
        excludes.append('ResourceErrorCF.cpp')
        excludes.append('RunLoopCF.cpp')
        
        # once we move over to the new FPD implementation, remove this.
        excludes.append('FontPlatformData.cpp')
        
        # we need a better system to exclude CF stuff
        excludes.append('HyphenationCF.cpp')
        
        if sys.platform.startswith('darwin'):
            webcore.includes += ' Source/WebKit/mac/WebCoreSupport Source/WebCore/platform/mac'
            webcore.source += ' Source/WebKit/mac/WebCoreSupport/WebSystemInterface.mm'
            
        if building_on_win32:
            for wxlib in bld.env['LIB_WX']:
                wx_version = wxpresets.get_wx_version(os.environ['WXWIN'])
                if int(wx_version[1]) % 2 == 1:
                    wxlib = wxlib.replace(''.join(wx_version[:2]), ''.join(wx_version))
                wxlibname = os.path.join(bld.env['LIBPATH_WX'][0], wxlib + '_vc.dll')
                print "Copying %s" % wxlibname
                if os.path.exists(wxlibname):
                    bld.install_files(webcore.install_path, [wxlibname])
        
            for dep in windows_deps:
                bld.install_files(webcore.install_path, [os.path.join(msvclibs_dir, dep)])
            
            if "CAIRO_ROOT" in os.environ and Options.options.cairo:
                cairo_bin_dir = os.path.join(os.environ["CAIRO_ROOT"], "bin") 
                for dep in glob.glob(os.path.join(cairo_bin_dir, "*.dll")):
                    bld.install_files(webcore.install_path, [os.path.join(cairo_bin_dir, dep)])
                    
    webcore.find_sources_in_dirs(full_dirs, excludes = excludes, exts=['.c', '.cpp'])

    bld.add_group()
    
    if Options.options.port == "wx":    
        bld.add_subdirs(['Tools/DumpRenderTree', 'Tools/wx/browser', 'Source/WebKit/wx/bindings/python'])
