#!/usr/bin/env python3
# -*- 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 itertools
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:
                    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._replacePrefix(input_lines, "JavaScriptCore/",               "$(PROJECT_DIR)/")
            input_lines = self._replacePrefix(input_lines, "JavaScriptCorePrivateHeaders/", "$(JAVASCRIPTCORE_PRIVATE_HEADERS_DIR)/")
            input_lines = self._replacePrefix(input_lines, "WebCore/",                      "$(PROJECT_DIR)/")
            input_lines = self._replacePrefix(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._get_derived_sources_dir() + "/" + line for line in output_lines]
            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.

    def _replaceSinglePrefix(self, line, prefix, replace_with):
        if line.startswith(prefix):
            return replace_with + line[len(prefix):]
        return line

    @util.LogEntryExit
    def _replacePrefix(self, lines, to_replace, replace_with):
        return set([self._replaceSinglePrefix(line, to_replace, replace_with) 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.
    #
    # The way we approach this gets a little involved. The straightforward
    # approach would be to fetch the value (a file system path) of the given
    # environment variable, and then replace that path with the variable name
    # in each of the given lines if the particular line is prefixed with that
    # path. So, for instance, converting:
    #
    #   /Volumes/Data/dev/webkit/OpenSource/WebKitBuild/Debug/DerivedSources/JavaScriptCore/ErrorPrototype.lut.h
    #
    # to:
    #
    #   $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/ErrorPrototype.lut.h
    #
    # However, there are issues with symlinks messing up that prefix matching.
    # It's possible for the entries in "lines" to contain fully resolved paths,
    # while the variable contains a path that has components that are symlinks.
    # These symlinks need to be resolved before the prefix matching can be
    # performed. That is, if BUILT_PRODUCTS_DIR contained
    # "/Users/Me/webkit/OpenSource/WebKitBuild/Debug", we would need to first
    # resolve that to "/Volumes/Data/dev/webkit/OpenSource/WebKitBuild/Debug"
    # before trying to replace it in any lines that are prefixed with it.
    #
    # Further, it's not always the case that the entries in "lines" contain
    # fully-resolved paths. For instance, some of them may refer to something
    # like <framework>.PrivateHeaders, which may be a symlink in a non-shallow
    # framework. If an incoming replacement value referred to that
    # PrivateHeaders directory, after being resolved, it now refers to the
    # versioned location (that is, <framework>/Versions/A/PrivateHeaders), and
    # will no longer match a path expressed in terms of
    # <framework>.PrivateHeaders. This means that each entry in "lines" also
    # needs to be fully resolved.
    #
    # And, yet, there's still a wrinkle. Sometimes we *don't* want to expand
    # the paths in "lines". An example of this occurs in DumpRenderTree, where
    # we wanted to convert:
    #
    #   /Volumes/Data/dev/webkit/OpenSource/Tools/DumpRenderTree/../TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
    #
    # to:
    #
    #   $(PROJECT_DIR)/../TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
    #
    # If we merely resolved the path, it would have been turned into:
    #
    #   /Volumes/Data/dev/webkit/OpenSource/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
    #
    # and it would no longer have a prefix that matched $PROJECT_DIR. So we
    # adopt an approach where we'll try both the raw and resolved paths in the
    # given environment variable, and the raw and resolved paths in each of the
    # entries in "lines".

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

        def _expand_if_abs(path):
            return os.path.realpath(path) if os.path.isabs(path) else path

        def _variations(path):
            def _gen(path):
                yield path
                yield _expand_if_abs(path)
            return (x for x in _gen(path))

        def _try_unexpand(prefix, line):
            new_line = self._replaceSinglePrefix(line, prefix + "/", "$({})/".format(variable_name))
            return new_line != line, new_line

        def _do_unexpand(line):
            for a_prefix, a_line in itertools.product(_variations(prefix), _variations(line)):
                changed, new_line = _try_unexpand(a_prefix, a_line)
                if changed:
                    break
            return new_line if changed else line

        return set(_do_unexpand(line) for line in lines)

    # 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", "WebKit")

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