#!/usr/bin/env python

# Copyright 2020 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Convert GN Xcode projects to platform and configuration independent targets.

GN generates Xcode projects that build one configuration only. However, typical
iOS development involves using the Xcode IDE to toggle the platform and
configuration. This script replaces the 'gn' configuration with 'Debug',
'Release' and 'Profile', and changes the ninja invocation to honor these
configurations.
"""

import argparse
import collections
import copy
import filecmp
import json
import hashlib
import os
import plistlib
import random
import shutil
import subprocess
import sys
import tempfile


class XcodeProject(object):

    def __init__(self, objects, counter=0):
        self.objects = objects
        self.counter = 0

    def AddObject(self, parent_name, obj):
        while True:
            self.counter += 1
            str_id = "%s %s %d" % (parent_name, obj['isa'], self.counter)
            new_id = hashlib.sha1(str_id).hexdigest()[:24].upper()

            # Make sure ID is unique. It's possible there could be an id
            # conflict since this is run after GN runs.
            if new_id not in self.objects:
                self.objects[new_id] = obj
                return new_id


def CopyFileIfChanged(source_path, target_path):
    """Copy |source_path| to |target_path| is different."""
    target_dir = os.path.dirname(target_path)
    if not os.path.isdir(target_dir):
        os.makedirs(target_dir)
    if (not os.path.exists(target_path) or
            not filecmp.cmp(source_path, target_path)):
        shutil.copyfile(source_path, target_path)


def LoadXcodeProjectAsJSON(path):
    """Return Xcode project at |path| as a JSON string."""
    return subprocess.check_output(
        ['plutil', '-convert', 'json', '-o', '-', path])


def WriteXcodeProject(output_path, json_string):
    """Save Xcode project to |output_path| as XML."""
    with tempfile.NamedTemporaryFile() as temp_file:
        temp_file.write(json_string)
        temp_file.flush()
        subprocess.check_call(['plutil', '-convert', 'xml1', temp_file.name])
        CopyFileIfChanged(temp_file.name, output_path)


def UpdateProductsProject(file_input, file_output, configurations, root_dir):
    """Update Xcode project to support multiple configurations.

    Args:
        file_input: path to the input Xcode project
        file_output: path to the output file
        configurations: list of string corresponding to the configurations that
        need to be supported by the tweaked Xcode projects, must contains at
        least one value.
    """
    json_data = json.loads(LoadXcodeProjectAsJSON(file_input))
    project = XcodeProject(json_data['objects'])

    objects_to_remove = []
    for value in project.objects.values():
        isa = value['isa']

        # Teach build shell script to look for the configuration and platform.
        if isa == 'PBXShellScriptBuildPhase':
            value['shellScript'] = value['shellScript'].replace(
                'ninja -C .',
                'ninja -C "../${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}"')

        # Add new configuration, using the first one as default.
        if isa == 'XCConfigurationList':
            value['defaultConfigurationName'] = configurations[0]
            objects_to_remove.extend(value['buildConfigurations'])

            build_config_template = project.objects[value['buildConfigurations']
                                                    [0]]
            build_settings = build_config_template['buildSettings']
            build_settings['CONFIGURATION_BUILD_DIR'] = (
                '$(PROJECT_DIR)/../$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)')
            build_settings['CODE_SIGN_IDENTITY'] = ''

            value['buildConfigurations'] = []
            for configuration in configurations:
                new_build_config = copy.copy(build_config_template)
                new_build_config['name'] = configuration
                value['buildConfigurations'].append(
                    project.AddObject('products', new_build_config))

    for object_id in objects_to_remove:
        del project.objects[object_id]

    AddMarkdownToProject(project, root_dir, json_data['rootObject'])

    objects = collections.OrderedDict(sorted(project.objects.iteritems()))
    WriteXcodeProject(file_output, json.dumps(json_data))


def AddMarkdownToProject(project, root_dir, root_object):
    list_files_cmd = ['git', '-C', root_dir, 'ls-files', '*.md']
    paths = subprocess.check_output(list_files_cmd).splitlines()
    ios_internal_dir = os.path.join(root_dir, 'ios_internal')
    if os.path.exists(ios_internal_dir):
        list_files_cmd = ['git', '-C', ios_internal_dir, 'ls-files', '*.md']
        ios_paths = subprocess.check_output(list_files_cmd).splitlines()
        paths.extend(["ios_internal/" + path for path in ios_paths])
    for path in paths:
        new_markdown_entry = {
            "fileEncoding": "4",
            "isa": "PBXFileReference",
            "lastKnownFileType": "net.daringfireball.markdown",
            "name": os.path.basename(path),
            "path": path,
            "sourceTree": "<group>"
        }
        new_markdown_entry_id = project.AddObject('sources', new_markdown_entry)
        folder = GetFolderForPath(project, root_object, os.path.dirname(path))
        folder['children'].append(new_markdown_entry_id)


def GetFolderForPath(project, rootObject, path):
    objects = project.objects
    # 'Sources' is always the first child of
    # project->rootObject->mainGroup->children.
    root = objects[objects[objects[rootObject]['mainGroup']]['children'][0]]
    if not path:
        return root
    for folder in path.split('/'):
        children = root['children']
        new_root = None
        for child in children:
            if (objects[child]['isa'] == 'PBXGroup' and
                    objects[child]['name'] == folder):
                new_root = objects[child]
                break
        if not new_root:
            # If the folder isn't found we could just cram it into the leaf
            # existing folder, but that leads to folders with tons of README.md
            # inside.
            new_group = {
                "children": [],
                "isa": "PBXGroup",
                "name": folder,
                "sourceTree": "<group>"
            }
            new_group_id = project.AddObject('sources', new_group)
            children.append(new_group_id)
            new_root = objects[new_group_id]
        root = new_root
    return root


def DisableNewBuildSystem(output_dir):
    """Disables the new build system due to crbug.com/852522 """
    xcwspacesharedsettings = os.path.join(output_dir, 'all.xcworkspace',
                                          'xcshareddata',
                                          'WorkspaceSettings.xcsettings')
    if os.path.isfile(xcwspacesharedsettings):
        json_data = json.loads(LoadXcodeProjectAsJSON(xcwspacesharedsettings))
    else:
        json_data = {}
    json_data['BuildSystemType'] = 'Original'
    WriteXcodeProject(xcwspacesharedsettings, json.dumps(json_data))


def ConvertGnXcodeProject(root_dir, input_dir, output_dir, configurations):
    '''Tweak the Xcode project generated by gn to support multiple
    configurations.

    The Xcode projects generated by "gn gen --ide" only supports a single
    platform and configuration (as the platform and configuration are set per
    output directory). This method takes as input such projects and add support
    for multiple configurations and platforms (to allow devs to select them in
    Xcode).

    Args:
        input_dir: directory containing the XCode projects created by "gn gen
            --ide"
        output_dir: directory where the tweaked Xcode projects will be saved
        configurations: list of string corresponding to the configurations that
            need to be supported by the tweaked Xcode projects, must contains at
            least one value.
    '''
    # Update products project.
    products = os.path.join('products.xcodeproj', 'project.pbxproj')
    product_input = os.path.join(input_dir, products)
    product_output = os.path.join(output_dir, products)
    UpdateProductsProject(product_input, product_output, configurations,
                          root_dir)

    # Copy all workspace.
    xcwspace = os.path.join('all.xcworkspace', 'contents.xcworkspacedata')
    CopyFileIfChanged(os.path.join(input_dir, xcwspace),
                      os.path.join(output_dir, xcwspace))

    # TODO(crbug.com/852522): Disable new BuildSystemType.
    DisableNewBuildSystem(output_dir)

    # TODO(crbug.com/679110): gn has been modified to remove 'sources.xcodeproj'
    # and keep 'all.xcworkspace' and 'products.xcodeproj'. The following code is
    # here to support both old and new projects setup and will be removed once
    # gn has rolled past it.
    sources = os.path.join('sources.xcodeproj', 'project.pbxproj')
    if os.path.isfile(os.path.join(input_dir, sources)):
        CopyFileIfChanged(os.path.join(input_dir, sources),
                          os.path.join(output_dir, sources))


def Main(args):
    parser = argparse.ArgumentParser(
        description='Convert GN Xcode projects for iOS.')
    parser.add_argument(
        'input', help='directory containing [product|all] Xcode projects.')
    parser.add_argument(
        'output', help='directory where to generate the iOS configuration.')
    parser.add_argument('--add-config',
                        dest='configurations',
                        default=[],
                        action='append',
                        help='configuration to add to the Xcode project')
    parser.add_argument('--root',
                        type=os.path.abspath,
                        required=True,
                        help='root directory of the project')
    args = parser.parse_args(args)

    if not os.path.isdir(args.input):
        sys.stderr.write('Input directory does not exists.\n')
        return 1

    required = set(['products.xcodeproj', 'all.xcworkspace'])
    if not required.issubset(os.listdir(args.input)):
        sys.stderr.write(
            'Input directory does not contain all necessary Xcode projects.\n')
        return 1

    if not args.configurations:
        sys.stderr.write(
            'At least one configuration required, see --add-config.\n')
        return 1

    ConvertGnXcodeProject(args.root, args.input, args.output,
                          args.configurations)


if __name__ == '__main__':
    sys.exit(Main(sys.argv[1:]))
