#!/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 re
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(dir=self._get_temp_dir()) as input, \
                tempfile.NamedTemporaryFile(dir=self._get_temp_dir()) 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).

            input_lines = self._get_file_lines(input.name)
            output_lines = self._get_file_lines(output.name)

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

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

            output_lines = self._replace(output_lines, "^", self._get_derived_sources_dir() + "/")
            output_lines = self._unexpand(output_lines, "BUILT_PRODUCTS_DIR")

            self.added_lines_input_derived = self._find_added_lines(input_lines, self._get_input_derived_xcfilelist_project_path())
            self.added_lines_output_derived = self._find_added_lines(output_lines, 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(dir=self._get_temp_dir()) 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)

            input_lines = None
            output_lines = self._get_file_lines(output.name)

            output_lines = self._unexpand(output_lines, "BUILT_PRODUCTS_DIR")

            self.added_lines_input_unified = self._find_added_lines(input_lines, self._get_input_unified_xcfilelist_project_path())
            self.added_lines_output_unified = self._find_added_lines(output_lines, 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, lines, to_replace, replace_with):
        return set([re.sub(to_replace, replace_with, line) for line in lines])

    # 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, lines, variable_name):
        to_replace = self._getenv(variable_name)
        if not to_replace:
            return lines
        return self._replace(lines, "^{}/".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()

        def get_lines(source):
            return source if isinstance(source, set) else set(source) if isinstance(source, list) else self._get_file_lines(source)

        source_lines = get_lines(source)
        dest_lines = get_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

    @util.LogEntryExit
    def _get_temp_dir(self):
        return self.application.get_xcode_project_temp_dir()


class JavaScriptCoreGenerator(BaseGenerator):
    VALID_PLATFORMS = ("macosx", "iphoneos", "iphonesimulator", "watchos", "watchsimulator", "appletvos", "appletvsimulator")
    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", "iphoneos", "iphonesimulator", "watchos", "watchsimulator", "appletvos", "appletvsimulator")
    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", "iphoneos", "iphonesimulator", "watchos", "watchsimulator", "appletvos", "appletvsimulator")
    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 WebKitLegacyGenerator(BaseGenerator):
    VALID_PLATFORMS = ("macosx", "iphoneos", "iphonesimulator", "watchos", "watchsimulator", "appletvos", "appletvsimulator")
    VALID_CONFIGURATIONS = ("Debug", "Release", "Production")

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

    @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")


class TestWebKitAPIGenerator(BaseGenerator):
    VALID_PLATFORMS = ("macosx", "iphoneos", "iphonesimulator", "watchos", "watchsimulator", "appletvos", "appletvsimulator")
    VALID_CONFIGURATIONS = ("Debug", "Release", "Production")

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

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