#!/usr/bin/env python
#
# Copyright 2017 The Fuchsia Authors. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT HOLDERS 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.


import sys
import os
import shutil
import subprocess

WEBKIT_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
BUILD_DIR = os.path.join(WEBKIT_ROOT, 'WebKitBuild', 'Debug')

known_targets = [
  ('Source/JavaScriptCore', 'JavaScriptCore'),
  ('Source/WTF/wtf', 'wtf'),
  ('Source/WebCore', 'WebCore'),
  ('Source/WebKit', 'WebKit'),
  ('Tools/MiniBrowser', 'MiniBrowser'),
]

# Some files live inside the library directories but are intended for building into standalone
# executables, so we exclude them from the library source listings.
executable_source_files = [
    'LLIntOffsetsExtractor.cpp',
    'testWASM.cpp',
    'testair.cpp',
    'testb3.cpp',
    'jsc.cpp',
]
# These files reference undefined symbols and themselves define symbols that aren't used anywhere,
# so we exclude them from our build files.
bad_source_files = executable_source_files + [
    'DNSResolveQueue.cpp',
    'SynchronousLoaderClient.cpp',
]
source_lists = {}

def append_to_source_list(target, filename):
    if source_lists.has_key(target):
        source_lists[target].append(filename)
    else:
        source_lists[target] = [filename]

def process_compile(line):
    components = line.rstrip().split(' ')
    source = os.path.relpath(components[-1])
    if os.path.basename(source) in bad_source_files:
        # Skip files that are their own mains
        return
    if 'DerivedSources' in source:
        derived_path = os.path.relpath(source, os.path.join(BUILD_DIR, 'DerivedSources'))
        component = os.path.dirname(derived_path)
        filename = os.path.basename(derived_path)
        dest = os.path.join(WEBKIT_ROOT, 'DerivedSources', component, filename)
        target = component.replace('/', '_') + 'DerivedSources'
        append_to_source_list(target, os.path.relpath(dest, WEBKIT_ROOT))
        # TODO: handle generated files
        # print 'generated file %s' % source
        return
    known = False
    for target in known_targets:
        if source.startswith(target[0]):
            append_to_source_list(target[1], source)
            known = True
            break
    if not known:
        print('unknown target %s, line %s' % (source, line))

def buildlog():
    ninja = os.path.join(os.path.dirname(os.path.dirname(WEBKIT_ROOT)), 'buildtools', 'ninja')
    # Hack: Nuke the ninja log to force full rebuilds
    dot_ninja_log = os.path.join(BUILD_DIR, '.ninja_log')
    if os.path.exists(dot_ninja_log):
        os.remove(dot_ninja_log)
    return subprocess.check_output([ninja, '-v', '-n'], cwd=BUILD_DIR)


def main():
    # Grab the list of files to compile from the build log
    print('Processing file list')
    log = buildlog()
    for line in log:
        # Figure out what kind of statement this is
        if 'clang++ --sysroot' in line or 'clang --sysroot' in line:
            if not '-o bin/' in line:
                process_compile(line)
    for entry in source_lists:
        with open(os.path.join(WEBKIT_ROOT, entry + '.gni'), 'w') as gni:
            gni.write('''
%s_sources = [
''' % entry)
            for source in sorted(source_lists[entry]):
                gni.write('  "%s",\n' % source)
            gni.write('''
]
''')
    derived_source_dir = os.path.join(BUILD_DIR, 'DerivedSources')
    derived_source_header_guard_substring = derived_source_dir.replace('/', '_').upper()
    print('Copying derived sources')
     # Copy all source and header files from DerivedSources in the build directory to our location
     # in the source directory.
    for entry in os.walk(derived_source_dir):
        dirpath, dirnames, filenames = entry
        for filename in filenames:
            ext = os.path.splitext(filename)[1]
            if not ext in ['.h', '.cpp', '.c']:
                continue
            # LLIntAssembly.h is treated specially since it differs for release and debug builds -
            # see below.
            if filename == 'LLIntAssembly.h':
                continue
            source = os.path.join(dirpath, filename)
            dest = os.path.join(WEBKIT_ROOT, os.path.relpath(source, BUILD_DIR))
            if not os.path.exists(os.path.dirname(dest)):
                os.makedirs(os.path.dirname(dest))
            with open(source) as source_file:
                contents = source_file.read()
                # Turn all paths to derived sources into source-relative paths.
                replaced_contents = contents.replace(BUILD_DIR + '/DerivedSources', 'DerivedSources')
                # Turn all absolute paths in the source dir into root-relative paths.
                replaced_contents = replaced_contents.replace(WEBKIT_ROOT + '/', '')
                # Turn generated header guards referencing full paths into relative.
                replaced_contents = replaced_contents.replace(derived_source_header_guard_substring,
                        '_DERIVED_SOURCES')
                with open(dest, 'w') as dest_file:
                    dest_file.write(replaced_contents)

    # LLIntAssembly.h is different in debug vs release builds, unlike other generated files.
    # To keep the debug and release versions separate, copy the two versions into different
    # directories. BUILD.gn adds the appropriate directory to the include path.
    for mode in ['Debug', 'Release']:
        dest_dir = os.path.join(WEBKIT_ROOT, 'DerivedSources', 'JavaScriptCore', mode)
        if not os.path.exists(dest_dir):
            os.makedirs(dest_dir)
        source = os.path.join(WEBKIT_ROOT, 'WebKitBuild', mode, 'DerivedSources',
        'JavaScriptCore', 'LLIntAssembly.h')
        shutil.copy(source, dest_dir)

    print('Copying cmakeconfig.h')
    # Copy cmakeconfig.h somewhere more useful
    config_path = os.path.join(WEBKIT_ROOT, 'Source', 'config')
    if not os.path.exists(config_path):
        os.makedirs(config_path)
    shutil.copy(os.path.join(BUILD_DIR, 'cmakeconfig.h'), config_path)
    print('Done!')


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