#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019 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 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 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.

# BaseGenerator is the base class for generating new .xcfilelist content. Most
# of the implementation is provided in this base class. Subclasses are created
# to provide project-specific information, such as the path to the project file
# and valid platform and configuration information.
#
# Instances of this class are create for each project/platform/configuration
# triple. For each triple, .xcfilelist content is generated and compared to the
# file that ultimately will contain that information. Any new lines are
# determined and remembered for later addition to that destination file.
#
# Instances of this class can operate in either of two contexts. First, it's
# possible for Xcode projects to invoke this script in order to keep their
# .xcfilelist files up-to-date. In that case, this script starts out running in
# the context of Xcode and it can just go ahead and generate the new content.
# Alternatively, it's possible for someone to invoke this script from the
# command line. In that case, this script needs to sublaunch itself in order to
# expose itself to the environment variables that Xcode establishes during
# builds. This script thus starts out as a free-standing script, creates a
# BaseGenerator for the .xcfilelist content it needs to create, sub-launches
# itself, and then creates another BaseGenerator to do the actual generation.
# When this inner instance of the script exits, it writes the results of the
# BaseGenerators to a temporary file. When the outer instance of the script
# resumes, it reads the information from that temporary file. That information
# is actually just a serialized (pickled) BaseGenerator instance and is
# restored as such. This restored BaseGenerator now replaces the original
# BaseGenerator in the outer script that caused it to be created, since the
# inner one is the one with all the xcfilelist information.

from __future__ import print_function

import os
import pickle
import tempfile
import traceback

import webkitpy.generate_xcfilelists_lib.util as util
from webkitpy.xcode import xcode_hash_for_path
from webkitpy.xcode.sdk import SDK
from webkitpy.common.attribute_saver import AttributeSaver


class BaseGenerator(object):
    __slots__ = (
        "application", "project_tag", "platform", "configuration", "triple",
        "ex_type", "ex_value", "ex_traceback",
        "added_lines_input_derived", "added_lines_output_derived", "added_lines_input_unified", "added_lines_output_unified",
        "cached_build_dirs")

    VALID_PLATFORMS = None
    VALID_CONFIGURATIONS = None

    @util.LogEntryExit
    def __init__(self, application, project_tag, platform, configuration):
        self.application = application
        self.project_tag = project_tag
        self.platform = platform
        self.configuration = configuration
        self.triple = (project_tag, platform, configuration)

        self.ex_type = None
        self.ex_value = None
        self.ex_traceback = None

        self.added_lines_input_derived = None
        self.added_lines_output_derived = None
        self.added_lines_input_unified = None
        self.added_lines_output_unified = None

        self.cached_build_dirs = None

    def __str__(self):
        return "project_tag = {}, platform = {}, configuration = {}, ex_type = {}, ex_value = {}, ex_traceback = {}, added_lines_input_derived = {}, added_lines_output_derived = {}, added_lines_input_unified = {}, added_lines_output_unified = {}, cached_build_dirs = {}".format(
            self.project_tag, self.platform, self.configuration,
            self.ex_type, self.ex_value, self.ex_traceback,
            self.added_lines_input_derived, self.added_lines_output_derived, self.added_lines_input_unified, self.added_lines_output_unified,
            self.cached_build_dirs)

    # Generate new .xcfilist list contents and return any new lines. This
    # generation is performed by relaunching ourselves under Xcode so that we
    # can operate in the context of its environment variables. When we relaunch
    # ourselves, we do so in a way that invokes this class's generate()
    # method. Any results from generate are written to a temporary file that
    # we set up here. When the relaunched instance completes, we reads those
    # results from the temporary file.

    @util.LogEntryExit
    def set_environment_and_generate(self):
        with tempfile.NamedTemporaryFile() as pickle_file, tempfile.NamedTemporaryFile() as debug_file:
            sublaunch_args = [
                "PATH=\"{}:${{PATH}}\"".format(self._getenv("PATH")),  # Xcode will "sanitize" PATH, such that Python is no longer on it, so get /usr/bin back in PATH.
                "PYTHONPATH=\"{}\"".format(self._getenv("PYTHONPATH", "")),
                self.application.get_generate_xcfilelists_script_path(),
                "generate-inner",
                "--project", self.project_tag,
                "--platform", self.platform,
                "--configuration", self.configuration,
                "--pickle-file", pickle_file.name]
            if self.application.cmd_line_args.debug:
                sublaunch_args += [
                    "--debug",
                    "--debug-file", debug_file.name]
            if self.application.cmd_line_args.quiet:
                sublaunch_args.append("--quiet")

            try:
                self._sublaunch_under_xcode(sublaunch_args)
            finally:
                # If xcodebuild returns an error, we want to at least display the
                # debugging information.
                if self.application.cmd_line_args.debug:
                    for line in debug_file:
                        util.debug_log("{}".format(line.rstrip()))

            generators = []
            while True:
                try:
                    generator = pickle.load(pickle_file)
                    generator.application = self.application
                    generators.append(generator)
                except EOFError as e:
                    break
            return generators

    # Relaunch this script under Xcode. This is performed by launching Xcode,
    # pointing it to the project that we are processing as well as a build
    # target that will re-execute us as a custom build step.

    @util.LogEntryExit
    def _sublaunch_under_xcode(self, sublaunch_args):
        xcode_parameters = [
            "xcodebuild",
            "-project", self._get_project_file_path(),
            "-sdk", SDK.get_preferred_sdk_for_platform(self.platform).as_xcode_specification(),
            "-configuration", self.configuration,
            "-target", "Apply Configuration to XCFileLists",
            "SYMROOT={}".format(self._get_sym_root()),
            "OBJROOT={}".format(self._get_obj_root()),
            "SHARED_PRECOMPS_DIR={}".format(self._get_shared_precomps_dir())]

        # TODO: sublaunch_args will contain the path to the script to
        # sublaunch. There might be a problem if there's a space in that path.
        util.subprocess_run(xcode_parameters,
            env={"WK_SUBLAUNCH_SCRIPT_PARAMETERS": " ".join(sublaunch_args)})

    # Generate the .xcfilelist content. Save the results internally as sets of
    # new lines to be added to the .xcfilelist files. These new lines can be
    # merged into those files if the user specified a "generate" command, or
    # can be reported in a "check" command.

    @util.LogEntryExit
    def generate(self):
        self._generate_derived()
        self._generate_unified()

    # Merge any saved added lines to their ultimate destinations.

    @util.LogEntryExit
    def merge(self):
        self._merge_derived()
        self._merge_unified()

    @util.LogEntryExit
    def pickle_to_file(self, f):
        # We don't want to pickle the application reference
        # We can't seem to pickle ex_traceback: PicklingError: Can't pickle <type 'traceback'>: it's not found as __builtin__.traceback
        with AttributeSaver(self, "application"), AttributeSaver(self, "ex_traceback"):
            pickle.dump(self, f, pickle.HIGHEST_PROTOCOL)

    # Return whether or not any new lines for any .xcfilelist files were
    # discovered.

    @util.LogEntryExit
    def has_action(self):
        return (self.added_lines_input_derived or
                self.added_lines_output_derived or
                self.added_lines_input_unified or
                self.added_lines_output_unified)

    # If any errors occur during the generation of .xcfilelist content, they
    # are remembered internally for later processing. This function returns
    # whether or not any such error occurred with this generator.

    @util.LogEntryExit
    def has_error(self):
        return self.ex_type

    # Return whether or not the combination of project, platform, and
    # configuration is valid (which is to say, if, for example, the given
    # project can be built for the given platform and configuration).

    @util.LogEntryExit
    def is_valid(self):
        return (self.platform in self.__class__.VALID_PLATFORMS and
                self.configuration in self.__class__.VALID_CONFIGURATIONS)

    # If an error/exception occurred and was recorded (that is, if has_error()
    # returns true), report that error to the console.

    @util.LogEntryExit
    def report_error(self):
        try:
            if self.ex_value:
                raise self.ex_value
        except KeyboardInterrupt:
            print("### Canceled")
        except util.CalledProcessError as e:
            print("### Error {} calling subprocess: {}".format(e.args[0], e.args[1]))
            if e.args[2]:
                print("### stdout = {}".format(e.args[2]))
            if e.args[3]:
                print("### stderr = {}".format(e.args[3]))
        except util.InvalidConfigurationError as e:
            print("### Invalid configuration: {}".format(e))
            return os.EX_USAGE
        except BaseException:
            traceback.print_exception(self.ex_type, self.ex_value, self.ex_traceback)
            return os.EX_SOFTWARE

    # Generate .xcfilelist content for the "Generate Derived Sources" build
    # phase.

    @util.LogEntryExit
    def _generate_derived(self):
        script = self._get_generate_derived_sources_script()
        if not script:
            return

        with tempfile.NamedTemporaryFile() as input, tempfile.NamedTemporaryFile() as output:
            (stdout, stderr) = util.subprocess_run(
                    [script,
                        "NO_SUPPLEMENTAL_FILES=1",
                        "--no-builtin-rules",
                        "--dry-run",
                        "--always-make",
                        "--debug=abvijm",
                        "all"])
            stdout = stdout.encode() if isinstance(stdout, str) else stdout
            (stdout, stderr) = util.subprocess_run(
                    [self.application.get_extract_dependencies_from_makefile_script(),
                        "--input", input.name,
                        "--output", output.name],
                    input=stdout)

            # TODO: Make this generator-specific (there's no need to reference
            # WebCore, for example, when processing the JavaScriptCore
            # project).

            self._replace(input.name, "^JavaScriptCore/",               "$(PROJECT_DIR)/")
            self._replace(input.name, "^JavaScriptCorePrivateHeaders/", "$(JAVASCRIPTCORE_PRIVATE_HEADERS_DIR)/")
            self._replace(input.name, "^WebCore/",                      "$(PROJECT_DIR)/")
            self._replace(input.name, "^WebKit2PrivateHeaders/",        "$(WEBKIT2_PRIVATE_HEADERS_DIR)/")

            self._unexpand(input.name, "JAVASCRIPTCORE_PRIVATE_HEADERS_DIR")
            self._unexpand(input.name, "PROJECT_DIR")
            self._unexpand(input.name, "WEBCORE_PRIVATE_HEADERS_DIR")
            self._unexpand(input.name, "WEBKIT2_PRIVATE_HEADERS_DIR")
            self._unexpand(input.name, "WEBKITADDITIONS_HEADERS_FOLDER_PATH")
            self._unexpand(input.name, "BUILT_PRODUCTS_DIR")    # Do this last, since it's a prefix of some other variables and will "intercept" them if executed earlier than them.

            self._replace(output.name, "^", self._get_derived_sources_dir() + "/")
            self._unexpand(output.name, "BUILT_PRODUCTS_DIR")

            self.added_lines_input_derived = self._find_added_lines(input.name, self._get_input_derived_xcfilelist_project_path())
            self.added_lines_output_derived = self._find_added_lines(output.name, self._get_output_derived_xcfilelist_project_path())

    @util.LogEntryExit
    def _merge_derived(self):
        self._merge_added_lines(self.added_lines_input_derived, self._get_input_derived_xcfilelist_project_path())
        self._merge_added_lines(self.added_lines_output_derived, self._get_output_derived_xcfilelist_project_path())

    # Generate .xcfilelist content for the "Generate Unified Sources" build
    # phase.

    @util.LogEntryExit
    def _generate_unified(self):
        script = self._get_generate_unified_sources_script()
        if not script:
            return

        with tempfile.NamedTemporaryFile() as output:

            # We need to define BUILD_SCRIPTS_DIR so that the bash script we're
            # invoking can find the ruby script that it invokes. If we don't
            # define BUILD_SCRIPTS_DIR, the bash script we're invoking with try
            # to define its own value for BUILD_SCRIPTS_DIR, but it will do so
            # incorrectly for our purposes, leading to dire results.

            env = os.environ.copy()
            env["BUILD_SCRIPTS_DIR"] = self.application.get_build_scripts_dir()

            util.subprocess_run(
                    [script,
                        "--generate-xcfilelists",
                        "--output-xcfilelist-path", output.name],
                    env=env)

            self._unexpand(output.name, "BUILT_PRODUCTS_DIR")

            self.added_lines_input_unified = self._find_added_lines(None, self._get_input_unified_xcfilelist_project_path())
            self.added_lines_output_unified = self._find_added_lines(output.name, self._get_output_unified_xcfilelist_project_path())

    @util.LogEntryExit
    def _merge_unified(self):
        self._merge_added_lines(self.added_lines_input_unified, self._get_input_unified_xcfilelist_project_path())
        self._merge_added_lines(self.added_lines_output_unified, self._get_output_unified_xcfilelist_project_path())

    # Utility for post-processing the initial .xcfilelist content. Used to
    # replace text in the file.

    @util.LogEntryExit
    def _replace(self, file_name, to_replace, replace_with):
        util.subprocess_run([
            "sed", "-E", "-e",
            "s|{}|{}|".format(to_replace, replace_with),
            "-i", "''", file_name])

    # Utility for post-processing the initial .xcfilelist content. Used to
    # replace file path segments with the variables that represent those path
    # segments.

    @util.LogEntryExit
    def _unexpand(self, file_name, variable_name):
        to_replace = self._getenv(variable_name)
        if not to_replace:
            return

        self._replace(file_name, "^{}/".format(to_replace), "$({})/".format(variable_name))

    # Given a source file with new .xcfilelist content and a dest file that
    # contains the original/previous .xcfilelist content (that is, likely the
    # file that's checked into the repo), determine what, if any, new lines
    # there are in source that aren't in dest.

    @util.LogEntryExit
    def _find_added_lines(self, source, dest):
        if not source:
            return set()
        source_lines = set(source) if isinstance(source, list) else self._get_file_lines(source)
        dest_lines = set(dest) if isinstance(dest, list) else self._get_file_lines(dest)
        delta_lines = source_lines - dest_lines
        return delta_lines

    # Bottleneck routine for taking a set of new lines of .xcfilelist content
    # and adding them to their ultimate file/destination.

    @util.LogEntryExit
    def _merge_added_lines(self, added_lines, dest):
        if not added_lines:
            return
        dest_lines = self._get_file_lines(dest)
        merged_lines = sorted(set(added_lines) | dest_lines)
        merged_lines = [line + "\n" for line in merged_lines if line and not line.startswith("#")]
        merged_lines[0:0] = ["# This file is generated by the generate-xcfilelists script.\n"]
        with open(dest, "w") as f:
            f.writelines(merged_lines)

    # Utility to read a file and results the contents as a set of lines with
    # EOLs removed.

    @util.LogEntryExit
    def _get_file_lines(self, file):
        try:
            with open(file, "r") as f:
                return set([line.strip() for line in f])
        except:
            return set()

    # Wrapper to return environment variable values.

    @util.LogEntryExit
    def _getenv(self, variable_name, default=None):
        return os.environ.get(variable_name, default)

    # Return the path to the project file (the *.xcodeproj "file).

    @util.LogEntryExit
    def _get_project_file_path(self):
        assert False, """\
                Override this to return full path to the project file (e.g.,
                ".../Source/JavaScriptCore/JavaScriptCode.xcodeproj")."""

    # Return the path to the directory containing the project file and its
    # supporting files and directories (e.g., ".../Source/JavaScriptCore").

    @util.LogEntryExit
    def _get_project_dir(self):
        return os.path.dirname(self._get_project_file_path())

    # Return the project file name (e.g., "JavaScriptCore.xcodeproj").

    @util.LogEntryExit
    def _get_project_file_name(self):
        return os.path.basename(self._get_project_file_path())

    # Return the project name (e.g., "JavaScriptCore").

    @util.LogEntryExit
    def _get_project_name(self):
        return os.path.splitext(self._get_project_file_name())[0]

    # Return the path to the build output directory to use when the user has
    # indicated that they are building from the command line. Be sure to
    # support default command-line users, command-line users that set
    # WEBKIT_OUTPUTDIR, default Xcode users, and people like Jeff Miller who
    # configure a custom build output location for Xcode.

    @util.LogEntryExit
    def _get_sym_root(self):
        return self._get_build_dirs()[0]

    @util.LogEntryExit
    def _get_obj_root(self):
        return self._get_build_dirs()[1]

    @util.LogEntryExit
    def _get_shared_precomps_dir(self):
        return os.path.join(self._get_build_dirs()[1], "PrecompiledHeaders")

    # From Xcode;
    #
    #   export SYMROOT            =/Users/keith/Library/Developer/Xcode/DerivedData/Safari-bmjhivzkbpxamlajyexvkivfjbmb/Build/Products
    #   export OBJROOT            =/Users/keith/Library/Developer/Xcode/DerivedData/Safari-bmjhivzkbpxamlajyexvkivfjbmb/Build/Intermediates.noindex
    #   export SHARED_PRECOMPS_DIR=/Users/keith/Library/Developer/Xcode/DerivedData/Safari-bmjhivzkbpxamlajyexvkivfjbmb/Build/Intermediates.noindex/PrecompiledHeaders
    #
    # From command-line:
    #
    #   export SYMROOT            =/Volumes/Data/dev/webkit/OpenSource/WebKitBuild
    #   export OBJROOT            =/Volumes/Data/dev/webkit/OpenSource/WebKitBuild
    #   export SHARED_PRECOMPS_DIR=/Volumes/Data/dev/webkit/OpenSource/WebKitBuild/PrecompiledHeaders

    @util.LogEntryExit
    def _get_build_dirs(self):
        def define_xcode_build_dirs(self):
            # Delete any spurious ~/Library/Preferences/xcodebuild.plist, as this
            # file will interfere with any preferences set in the IDE. This
            # .plist file shouldn't really ever exist, so nuking it doesn't
            # cause any problems.

            xcodebuild_plist = os.path.join(os.path.expanduser("~"), "Library", "Preferences", "xcodebuild.plist")
            try:
                os.unlink(xcodebuild_plist)
            except:
                pass

            def read_xcode_user_default(key):
                try:
                    (stdout, stderr) = util.subprocess_run(["defaults", "read", "com.apple.dt.Xcode", key])
                    return stdout.strip()
                except util.CalledProcessError:
                    return None

            # The following is based on the logic in determineBaseProductDir()
            # in webkitdirs.pm and https://pewpewthespells.com/blog/xcode_build_locations.html.

            # Get the base directory for the build output. This will be some
            # default location (e.g., ~/Library/Developer/Xcode/DerivedData),
            # an absolute path, or a project-relative path.

            ide_custom_derived_data_location = read_xcode_user_default("IDECustomDerivedDataLocation")

            # Path not specified; use the default.

            if not ide_custom_derived_data_location:
                base_dir = os.path.join(os.path.expanduser("~"), "Library", "Developer", "Xcode", "DerivedData")

            # An absolute path is specified; use it.

            elif os.path.isabs(ide_custom_derived_data_location):
                base_dir = ide_custom_derived_data_location

            # A relative path is specified; append it to the project path.

            else:
                base_dir = os.path.join(self._get_project_dir(), ide_custom_derived_data_location)

            # Get the specification for how the build output should be stored
            # withing that base directory. This will be some unique directory
            # based on the hash of the project file path (e.g.,
            # "Safari-sdlfkhasalksdjfhsdfhlksf"), some shared directory (e.g.,
            # "Build"), or even something that might be an absolute path.

            ide_build_location_style = read_xcode_user_default("IDEBuildLocationStyle")

            # Create a unique directory within the base directory based on
            # project name and hash of its full path.
            #
            #    IDEBuildLocationStyle      = Unique;       # This is the default if not specified.

            if ide_build_location_style == "Unique" or not ide_build_location_style:
                workspace = os.path.abspath(self.application.cmd_line_args.xcode)
                build_dir = os.path.join(
                        base_dir,
                        os.path.splitext(os.path.basename(workspace))[0] + "-" + xcode_hash_for_path(workspace),
                        "Build")
                products_dir = os.path.join(build_dir, "Products")
                intermediates_dir = os.path.join(build_dir, "Intermediates.noindex")

            # Use a shared subdirectory; use the specified directory name.
            #
            #    IDEBuildLocationStyle      = Shared;
            #    IDESharedBuildFolderName       = Build;    # Relative to DerivedDataLocation

            elif ide_build_location_style == "Shared":
                build_dir = os.path.join(base_dir, read_xcode_user_default("IDESharedBuildFolderName"))
                products_dir = os.path.join(build_dir, "Products")
                intermediates_dir = os.path.join(build_dir, "Intermediates.noindex")

            # Use the saved products and intermediates paths and either use
            # them as relative to the DerivedData directory or the project
            # folder, or just use them as absolute addresses.
            #
            #    IDEBuildLocationStyle      = Custom;

            elif ide_build_location_style == "Custom":
                ide_build_location_type = read_xcode_user_default("IDECustomBuildLocationType")

                products_dir = read_xcode_user_default("IDECustomBuildProductsPath")
                intermediates_dir = read_xcode_user_default("IDECustomBuildIntermediatesPath")

                #    IDECustomBuildLocationType     = RelativeToDerivedData;
                #    IDECustomBuildIntermediatesPath    = "Build/Intermediates.noindex";
                #    IDECustomBuildProductsPath         = "Build/Products";
                #    IDECustomIndexStorePath            = "Index/DataStore";

                if ide_build_location_type == "RelativeToDerivedData":
                    products_dir = os.path.join(base_dir, products_dir)
                    intermediates_dir = os.path.join(base_dir, intermediates_dir)

                #    IDECustomBuildLocationType     = RelativeToWorkspace;
                #    IDECustomBuildIntermediatesPath    = "Build/Intermediates.noindex";
                #    IDECustomBuildProductsPath         = "Build/Products";
                #    IDECustomIndexStorePath            = "Index/DataStore";

                elif ide_build_location_type == "RelativeToWorkspace":
                    base_dir = self._get_project_dir(),
                    products_dir = os.path.join(base_dir, products_dir)
                    intermediates_dir = os.path.join(base_dir, intermediates_dir)

                #    IDECustomBuildLocationType     = Absolute;
                #    IDECustomBuildIntermediatesPath    = "/Users/joedeveloper/Desktop/Build/Intermediates.noindex";
                #    IDECustomBuildProductsPath         = "/Users/joedeveloper/Desktop/Build/Products";
                #    IDECustomIndexStorePath            = "/Users/joedeveloper/Desktop/Index/DataStore";
                #    IDECustomDerivedDataLocation       = "/Users/joedeveloper/Library/Developer/Xcode/DerivedData";

                elif ide_build_location_type == "Absolute":
                    pass

                else:
                    assert False, "Unknown/unsupported location type"
            else:
                assert False, "Unknown/unsupported style"

            return (products_dir, intermediates_dir)

        def define_command_line_build_dirs(self):
            products_dir = self._getenv("WEBKIT_OUTPUTDIR")
            if not products_dir:
                products_dir = os.path.join(self.application.get_opensource_dir(), "WebKitBuild")
            return (products_dir, products_dir)

        if not self.cached_build_dirs and self.application.cmd_line_args.xcode:
            self.cached_build_dirs = define_xcode_build_dirs(self)
        if not self.cached_build_dirs:
            self.cached_build_dirs = define_command_line_build_dirs(self)
        return self.cached_build_dirs

    # Return the location of the DerivedSources directory. Conventionally, we
    # use $BUILT_PRODUCTS/DerivedSources/$PROJECT_NAME, but we may some day use
    # $DERIVED_FILE_DIR aka $DERIVED_FILES_DIR aka $DERIVED_SOURCES_DIR, when
    # the projects have been updated to use them.

    @util.LogEntryExit
    def _get_derived_sources_dir(self):
        return os.path.join(self.application.get_xcode_built_products_dir(), "DerivedSources", self._get_project_name())

    # Return the location for the xcfilelists.

    @util.LogEntryExit
    def _get_xcfilelist_dir(self):
        return self._get_project_dir()

    # Return the paths to the actual xcfilelists.

    @util.LogEntryExit
    def _get_input_derived_xcfilelist_project_path(self):
        return os.path.join(self._get_xcfilelist_dir(), "DerivedSources-input.xcfilelist")

    @util.LogEntryExit
    def _get_output_derived_xcfilelist_project_path(self):
        return os.path.join(self._get_xcfilelist_dir(), "DerivedSources-output.xcfilelist")

    @util.LogEntryExit
    def _get_input_unified_xcfilelist_project_path(self):
        return os.path.join(self._get_xcfilelist_dir(), "UnifiedSources-input.xcfilelist")

    @util.LogEntryExit
    def _get_output_unified_xcfilelist_project_path(self):
        return os.path.join(self._get_xcfilelist_dir(), "UnifiedSources-output.xcfilelist")

    # Return the paths to the scripts that generate the derived sources.

    @util.LogEntryExit
    def _get_generate_derived_sources_script(self):
        return None

    @util.LogEntryExit
    def _get_generate_unified_sources_script(self):
        return None


class JavaScriptCoreGenerator(BaseGenerator):
    VALID_PLATFORMS = ("macosx", "iosmac", "iphoneos", "watchos")
    VALID_CONFIGURATIONS = ("Debug", "Release", "Production", "Profiling")

    @util.LogEntryExit
    def _get_project_file_path(self):
        return os.path.join(self.application.get_opensource_dir(), "Source", "JavaScriptCore", "JavaScriptCore.xcodeproj")

    @util.LogEntryExit
    def _get_generate_derived_sources_script(self):
        return os.path.join(self._get_project_dir(), "Scripts", "generate-derived-sources.sh")

    @util.LogEntryExit
    def _get_generate_unified_sources_script(self):
        return os.path.join(self._get_project_dir(), "Scripts", "generate-unified-sources.sh")


class WebCoreGenerator(BaseGenerator):
    VALID_PLATFORMS = ("macosx", "iosmac", "iphoneos", "watchos")
    VALID_CONFIGURATIONS = ("Debug", "Release", "Production")

    @util.LogEntryExit
    def _get_project_file_path(self):
        return os.path.join(self.application.get_opensource_dir(), "Source", "WebCore", "WebCore.xcodeproj")

    @util.LogEntryExit
    def _get_generate_derived_sources_script(self):
        return os.path.join(self._get_project_dir(), "Scripts", "generate-derived-sources.sh")

    @util.LogEntryExit
    def _get_generate_unified_sources_script(self):
        return os.path.join(self._get_project_dir(), "Scripts", "generate-unified-sources.sh")


class WebKitGenerator(BaseGenerator):
    VALID_PLATFORMS = ("macosx", "iosmac", "iphoneos", "watchos")
    VALID_CONFIGURATIONS = ("Debug", "Release", "Production")

    @util.LogEntryExit
    def _get_project_file_path(self):
        return os.path.join(self.application.get_opensource_dir(), "Source", "WebKit", "WebKit.xcodeproj")

    @util.LogEntryExit
    def _get_derived_sources_dir(self):
        return os.path.join(self.application.get_xcode_built_products_dir(), "DerivedSources", "WebKit2")

    @util.LogEntryExit
    def _get_generate_derived_sources_script(self):
        return os.path.join(self._get_project_dir(), "Scripts", "generate-derived-sources.sh")

    @util.LogEntryExit
    def _get_generate_unified_sources_script(self):
        return os.path.join(self._get_project_dir(), "Scripts", "generate-unified-sources.sh")


class DumpRenderTreeGenerator(BaseGenerator):
    VALID_PLATFORMS = ("macosx", )
    VALID_CONFIGURATIONS = ("Debug", "Release", "Production")

    @util.LogEntryExit
    def _get_project_file_path(self):
        return os.path.join(self.application.get_opensource_dir(), "Tools", "DumpRenderTree", "DumpRenderTree.xcodeproj")

    @util.LogEntryExit
    def _get_generate_derived_sources_script(self):
        return os.path.join(self._get_project_dir(), "Scripts", "generate-derived-sources.sh")


class WebKitTestRunnerGenerator(BaseGenerator):
    VALID_PLATFORMS = ("macosx", )
    VALID_CONFIGURATIONS = ("Debug", "Release", "Production")

    @util.LogEntryExit
    def _get_project_file_path(self):
        return os.path.join(self.application.get_opensource_dir(), "Tools", "WebKitTestRunner", "WebKitTestRunner.xcodeproj")

    @util.LogEntryExit
    def _get_generate_derived_sources_script(self):
        return os.path.join(self._get_project_dir(), "Scripts", "generate-derived-sources.sh")
