#!/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_config_template['buildSettings']['CONFIGURATION_BUILD_DIR'] = \
          '$(PROJECT_DIR)/../$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)'
      build_config_template['buildSettings']['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:]))
