#!/usr/bin/env python
# Copyright (c) 2012 Google Inc. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Utility functions to perform Xcode-style build steps.

These functions are executed via gyp-mac-tool when using the Makefile generator.
"""

import fcntl
import fnmatch
import glob
import json
import os
import plistlib
import re
import shutil
import string
import subprocess
import sys
import tempfile


def main(args):
  executor = MacTool()
  exit_code = executor.Dispatch(args)
  if exit_code is not None:
    sys.exit(exit_code)


class MacTool(object):
  """This class performs all the Mac tooling steps. The methods can either be
  executed directly, or dispatched from an argument list."""

  def Dispatch(self, args):
    """Dispatches a string command to a method."""
    if len(args) < 1:
      raise Exception("Not enough arguments")

    method = "Exec%s" % self._CommandifyName(args[0])
    return getattr(self, method)(*args[1:])

  def _CommandifyName(self, name_string):
    """Transforms a tool name like copy-info-plist to CopyInfoPlist"""
    return name_string.title().replace('-', '')

  def ExecCopyBundleResource(self, source, dest, convert_to_binary):
    """Copies a resource file to the bundle/Resources directory, performing any
    necessary compilation on each resource."""
    extension = os.path.splitext(source)[1].lower()
    if os.path.isdir(source):
      # Copy tree.
      # TODO(thakis): This copies file attributes like mtime, while the
      # single-file branch below doesn't. This should probably be changed to
      # be consistent with the single-file branch.
      if os.path.exists(dest):
        shutil.rmtree(dest)
      shutil.copytree(source, dest)
    elif extension == '.xib':
      return self._CopyXIBFile(source, dest)
    elif extension == '.storyboard':
      return self._CopyXIBFile(source, dest)
    elif extension == '.strings':
      self._CopyStringsFile(source, dest, convert_to_binary)
    else:
      shutil.copy(source, dest)

  def _CopyXIBFile(self, source, dest):
    """Compiles a XIB file with ibtool into a binary plist in the bundle."""

    # ibtool sometimes crashes with relative paths. See crbug.com/314728.
    base = os.path.dirname(os.path.realpath(__file__))
    if os.path.relpath(source):
      source = os.path.join(base, source)
    if os.path.relpath(dest):
      dest = os.path.join(base, dest)

    args = ['xcrun', 'ibtool', '--errors', '--warnings', '--notices',
        '--output-format', 'human-readable-text', '--compile', dest, source]
    ibtool_section_re = re.compile(r'/\*.*\*/')
    ibtool_re = re.compile(r'.*note:.*is clipping its content')
    ibtoolout = subprocess.Popen(args, stdout=subprocess.PIPE)
    current_section_header = None
    for line in ibtoolout.stdout:
      if ibtool_section_re.match(line):
        current_section_header = line
      elif not ibtool_re.match(line):
        if current_section_header:
          sys.stdout.write(current_section_header)
          current_section_header = None
        sys.stdout.write(line)
    return ibtoolout.returncode

  def _ConvertToBinary(self, dest):
    subprocess.check_call([
        'xcrun', 'plutil', '-convert', 'binary1', '-o', dest, dest])

  def _CopyStringsFile(self, source, dest, convert_to_binary):
    """Copies a .strings file using iconv to reconvert the input into UTF-16."""
    input_code = self._DetectInputEncoding(source) or "UTF-8"

    # Xcode's CpyCopyStringsFile / builtin-copyStrings seems to call
    # CFPropertyListCreateFromXMLData() behind the scenes; at least it prints
    #     CFPropertyListCreateFromXMLData(): Old-style plist parser: missing
    #     semicolon in dictionary.
    # on invalid files. Do the same kind of validation.
    import CoreFoundation
    s = open(source, 'rb').read()
    d = CoreFoundation.CFDataCreate(None, s, len(s))
    _, error = CoreFoundation.CFPropertyListCreateFromXMLData(None, d, 0, None)
    if error:
      return

    fp = open(dest, 'wb')
    fp.write(s.decode(input_code).encode('UTF-16'))
    fp.close()

    if convert_to_binary == 'True':
      self._ConvertToBinary(dest)

  def _DetectInputEncoding(self, file_name):
    """Reads the first few bytes from file_name and tries to guess the text
    encoding. Returns None as a guess if it can't detect it."""
    fp = open(file_name, 'rb')
    try:
      header = fp.read(3)
    except e:
      fp.close()
      return None
    fp.close()
    if header.startswith("\xFE\xFF"):
      return "UTF-16"
    elif header.startswith("\xFF\xFE"):
      return "UTF-16"
    elif header.startswith("\xEF\xBB\xBF"):
      return "UTF-8"
    else:
      return None

  def ExecCopyInfoPlist(self, source, dest, convert_to_binary, *keys):
    """Copies the |source| Info.plist to the destination directory |dest|."""
    # Read the source Info.plist into memory.
    fd = open(source, 'r')
    lines = fd.read()
    fd.close()

    # Insert synthesized key/value pairs (e.g. BuildMachineOSBuild).
    plist = plistlib.readPlistFromString(lines)
    if keys:
      plist = dict(plist.items() + json.loads(keys[0]).items())
    lines = plistlib.writePlistToString(plist)

    # Go through all the environment variables and replace them as variables in
    # the file.
    IDENT_RE = re.compile(r'[/\s]')
    for key in os.environ:
      if key.startswith('_'):
        continue
      evar = '${%s}' % key
      evalue = os.environ[key]
      lines = string.replace(lines, evar, evalue)

      # Xcode supports various suffices on environment variables, which are
      # all undocumented. :rfc1034identifier is used in the standard project
      # template these days, and :identifier was used earlier. They are used to
      # convert non-url characters into things that look like valid urls --
      # except that the replacement character for :identifier, '_' isn't valid
      # in a URL either -- oops, hence :rfc1034identifier was born.
      evar = '${%s:identifier}' % key
      evalue = IDENT_RE.sub('_', os.environ[key])
      lines = string.replace(lines, evar, evalue)

      evar = '${%s:rfc1034identifier}' % key
      evalue = IDENT_RE.sub('-', os.environ[key])
      lines = string.replace(lines, evar, evalue)

    # Remove any keys with values that haven't been replaced.
    lines = lines.split('\n')
    for i in range(len(lines)):
      if lines[i].strip().startswith("<string>${"):
        lines[i] = None
        lines[i - 1] = None
    lines = '\n'.join(filter(lambda x: x is not None, lines))

    # Write out the file with variables replaced.
    fd = open(dest, 'w')
    fd.write(lines)
    fd.close()

    # Now write out PkgInfo file now that the Info.plist file has been
    # "compiled".
    self._WritePkgInfo(dest)

    if convert_to_binary == 'True':
      self._ConvertToBinary(dest)

  def _WritePkgInfo(self, info_plist):
    """This writes the PkgInfo file from the data stored in Info.plist."""
    plist = plistlib.readPlist(info_plist)
    if not plist:
      return

    # Only create PkgInfo for executable types.
    package_type = plist['CFBundlePackageType']
    if package_type != 'APPL':
      return

    # The format of PkgInfo is eight characters, representing the bundle type
    # and bundle signature, each four characters. If that is missing, four
    # '?' characters are used instead.
    signature_code = plist.get('CFBundleSignature', '????')
    if len(signature_code) != 4:  # Wrong length resets everything, too.
      signature_code = '?' * 4

    dest = os.path.join(os.path.dirname(info_plist), 'PkgInfo')
    fp = open(dest, 'w')
    fp.write('%s%s' % (package_type, signature_code))
    fp.close()

  def ExecFlock(self, lockfile, *cmd_list):
    """Emulates the most basic behavior of Linux's flock(1)."""
    # Rely on exception handling to report errors.
    fd = os.open(lockfile, os.O_RDONLY|os.O_NOCTTY|os.O_CREAT, 0o666)
    fcntl.flock(fd, fcntl.LOCK_EX)
    return subprocess.call(cmd_list)

  def ExecFilterLibtool(self, *cmd_list):
    """Calls libtool and filters out '/path/to/libtool: file: foo.o has no
    symbols'."""
    libtool_re = re.compile(r'^.*libtool: file: .* has no symbols$')
    libtool_re5 = re.compile(
        r'^.*libtool: warning for library: ' +
        r'.* the table of contents is empty ' +
        r'\(no object file members in the library define global symbols\)$')
    env = os.environ.copy()
    # Ref:
    # http://www.opensource.apple.com/source/cctools/cctools-809/misc/libtool.c
    # The problem with this flag is that it resets the file mtime on the file to
    # epoch=0, e.g. 1970-1-1 or 1969-12-31 depending on timezone.
    env['ZERO_AR_DATE'] = '1'
    libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE, env=env)
    _, err = libtoolout.communicate()
    for line in err.splitlines():
      if not libtool_re.match(line) and not libtool_re5.match(line):
        print >>sys.stderr, line
    # Unconditionally touch the output .a file on the command line if present
    # and the command succeeded. A bit hacky.
    if not libtoolout.returncode:
      for i in range(len(cmd_list) - 1):
        if cmd_list[i] == "-o" and cmd_list[i+1].endswith('.a'):
          os.utime(cmd_list[i+1], None)
          break
    return libtoolout.returncode

  def ExecPackageFramework(self, framework, version):
    """Takes a path to Something.framework and the Current version of that and
    sets up all the symlinks."""
    # Find the name of the binary based on the part before the ".framework".
    binary = os.path.basename(framework).split('.')[0]

    CURRENT = 'Current'
    RESOURCES = 'Resources'
    VERSIONS = 'Versions'

    if not os.path.exists(os.path.join(framework, VERSIONS, version, binary)):
      # Binary-less frameworks don't seem to contain symlinks (see e.g.
      # chromium's out/Debug/org.chromium.Chromium.manifest/ bundle).
      return

    # Move into the framework directory to set the symlinks correctly.
    pwd = os.getcwd()
    os.chdir(framework)

    # Set up the Current version.
    self._Relink(version, os.path.join(VERSIONS, CURRENT))

    # Set up the root symlinks.
    self._Relink(os.path.join(VERSIONS, CURRENT, binary), binary)
    self._Relink(os.path.join(VERSIONS, CURRENT, RESOURCES), RESOURCES)

    # Back to where we were before!
    os.chdir(pwd)

  def _Relink(self, dest, link):
    """Creates a symlink to |dest| named |link|. If |link| already exists,
    it is overwritten."""
    if os.path.lexists(link):
      os.remove(link)
    os.symlink(dest, link)

  def ExecCompileXcassets(self, keys, *inputs):
    """Compiles multiple .xcassets files into a single .car file.

    This invokes 'actool' to compile all the inputs .xcassets files. The
    |keys| arguments is a json-encoded dictionary of extra arguments to
    pass to 'actool' when the asset catalogs contains an application icon
    or a launch image.

    Note that 'actool' does not create the Assets.car file if the asset
    catalogs does not contains imageset.
    """
    command_line = [
      'xcrun', 'actool', '--output-format', 'human-readable-text',
      '--compress-pngs', '--notices', '--warnings', '--errors',
    ]
    is_iphone_target = 'IPHONEOS_DEPLOYMENT_TARGET' in os.environ
    if is_iphone_target:
      platform = os.environ['CONFIGURATION'].split('-')[-1]
      if platform not in ('iphoneos', 'iphonesimulator'):
        platform = 'iphonesimulator'
      command_line.extend([
          '--platform', platform, '--target-device', 'iphone',
          '--target-device', 'ipad', '--minimum-deployment-target',
          os.environ['IPHONEOS_DEPLOYMENT_TARGET'], '--compile',
          os.path.abspath(os.environ['CONTENTS_FOLDER_PATH']),
      ])
    else:
      command_line.extend([
          '--platform', 'macosx', '--target-device', 'mac',
          '--minimum-deployment-target', os.environ['MACOSX_DEPLOYMENT_TARGET'],
          '--compile',
          os.path.abspath(os.environ['UNLOCALIZED_RESOURCES_FOLDER_PATH']),
      ])
    if keys:
      keys = json.loads(keys)
      for key, value in keys.iteritems():
        arg_name = '--' + key
        if isinstance(value, bool):
          if value:
            command_line.append(arg_name)
        elif isinstance(value, list):
          for v in value:
            command_line.append(arg_name)
            command_line.append(str(v))
        else:
          command_line.append(arg_name)
          command_line.append(str(value))
    # Note: actool crashes if inputs path are relative, so use os.path.abspath
    # to get absolute path name for inputs.
    command_line.extend(map(os.path.abspath, inputs))
    subprocess.check_call(command_line)

  def ExecMergeInfoPlist(self, output, *inputs):
    """Merge multiple .plist files into a single .plist file."""
    merged_plist = {}
    for path in inputs:
      plist = self._LoadPlistMaybeBinary(path)
      self._MergePlist(merged_plist, plist)
    plistlib.writePlist(merged_plist, output)

  def ExecCodeSignBundle(self, key, resource_rules, entitlements, provisioning):
    """Code sign a bundle.

    This function tries to code sign an iOS bundle, following the same
    algorithm as Xcode:
      1. copy ResourceRules.plist from the user or the SDK into the bundle,
      2. pick the provisioning profile that best match the bundle identifier,
         and copy it into the bundle as embedded.mobileprovision,
      3. copy Entitlements.plist from user or SDK next to the bundle,
      4. code sign the bundle.
    """
    resource_rules_path = self._InstallResourceRules(resource_rules)
    substitutions, overrides = self._InstallProvisioningProfile(
        provisioning, self._GetCFBundleIdentifier())
    entitlements_path = self._InstallEntitlements(
        entitlements, substitutions, overrides)
    subprocess.check_call([
        'codesign', '--force', '--sign', key, '--resource-rules',
        resource_rules_path, '--entitlements', entitlements_path,
        os.path.join(
            os.environ['TARGET_BUILD_DIR'],
            os.environ['FULL_PRODUCT_NAME'])])

  def _InstallResourceRules(self, resource_rules):
    """Installs ResourceRules.plist from user or SDK into the bundle.

    Args:
      resource_rules: string, optional, path to the ResourceRules.plist file
        to use, default to "${SDKROOT}/ResourceRules.plist"

    Returns:
      Path to the copy of ResourceRules.plist into the bundle.
    """
    source_path = resource_rules
    target_path = os.path.join(
        os.environ['BUILT_PRODUCTS_DIR'],
        os.environ['CONTENTS_FOLDER_PATH'],
        'ResourceRules.plist')
    if not source_path:
      source_path = os.path.join(
          os.environ['SDKROOT'], 'ResourceRules.plist')
    shutil.copy2(source_path, target_path)
    return target_path

  def _InstallProvisioningProfile(self, profile, bundle_identifier):
    """Installs embedded.mobileprovision into the bundle.

    Args:
      profile: string, optional, short name of the .mobileprovision file
        to use, if empty or the file is missing, the best file installed
        will be used
      bundle_identifier: string, value of CFBundleIdentifier from Info.plist

    Returns:
      A tuple containing two dictionary: variables substitutions and values
      to overrides when generating the entitlements file.
    """
    source_path, provisioning_data, team_id = self._FindProvisioningProfile(
        profile, bundle_identifier)
    target_path = os.path.join(
        os.environ['BUILT_PRODUCTS_DIR'],
        os.environ['CONTENTS_FOLDER_PATH'],
        'embedded.mobileprovision')
    shutil.copy2(source_path, target_path)
    substitutions = self._GetSubstitutions(bundle_identifier, team_id + '.')
    return substitutions, provisioning_data['Entitlements']

  def _FindProvisioningProfile(self, profile, bundle_identifier):
    """Finds the .mobileprovision file to use for signing the bundle.

    Checks all the installed provisioning profiles (or if the user specified
    the PROVISIONING_PROFILE variable, only consult it) and select the most
    specific that correspond to the bundle identifier.

    Args:
      profile: string, optional, short name of the .mobileprovision file
        to use, if empty or the file is missing, the best file installed
        will be used
      bundle_identifier: string, value of CFBundleIdentifier from Info.plist

    Returns:
      A tuple of the path to the selected provisioning profile, the data of
      the embedded plist in the provisioning profile and the team identifier
      to use for code signing.

    Raises:
      SystemExit: if no .mobileprovision can be used to sign the bundle.
    """
    profiles_dir = os.path.join(
        os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles')
    if not os.path.isdir(profiles_dir):
      print >>sys.stderr, (
          'cannot find mobile provisioning for %s' % bundle_identifier)
      sys.exit(1)
    provisioning_profiles = None
    if profile:
      profile_path = os.path.join(profiles_dir, profile + '.mobileprovision')
      if os.path.exists(profile_path):
        provisioning_profiles = [profile_path]
    if not provisioning_profiles:
      provisioning_profiles = glob.glob(
          os.path.join(profiles_dir, '*.mobileprovision'))
    valid_provisioning_profiles = {}
    for profile_path in provisioning_profiles:
      profile_data = self._LoadProvisioningProfile(profile_path)
      app_id_pattern = profile_data.get(
          'Entitlements', {}).get('application-identifier', '')
      for team_identifier in profile_data.get('TeamIdentifier', []):
        app_id = '%s.%s' % (team_identifier, bundle_identifier)
        if fnmatch.fnmatch(app_id, app_id_pattern):
          valid_provisioning_profiles[app_id_pattern] = (
              profile_path, profile_data, team_identifier)
    if not valid_provisioning_profiles:
      print >>sys.stderr, (
          'cannot find mobile provisioning for %s' % bundle_identifier)
      sys.exit(1)
    # If the user has multiple provisioning profiles installed that can be
    # used for ${bundle_identifier}, pick the most specific one (ie. the
    # provisioning profile whose pattern is the longest).
    selected_key = max(valid_provisioning_profiles, key=lambda v: len(v))
    return valid_provisioning_profiles[selected_key]

  def _LoadProvisioningProfile(self, profile_path):
    """Extracts the plist embedded in a provisioning profile.

    Args:
      profile_path: string, path to the .mobileprovision file

    Returns:
      Content of the plist embedded in the provisioning profile as a dictionary.
    """
    with tempfile.NamedTemporaryFile() as temp:
      subprocess.check_call([
          'security', 'cms', '-D', '-i', profile_path, '-o', temp.name])
      return self._LoadPlistMaybeBinary(temp.name)

  def _MergePlist(self, merged_plist, plist):
    """Merge |plist| into |merged_plist|."""
    for key, value in plist.iteritems():
      if isinstance(value, dict):
        merged_value = merged_plist.get(key, {})
        if isinstance(merged_value, dict):
          self._MergePlist(merged_value, value)
          merged_plist[key] = merged_value
        else:
          merged_plist[key] = value
      else:
        merged_plist[key] = value

  def _LoadPlistMaybeBinary(self, plist_path):
    """Loads into a memory a plist possibly encoded in binary format.

    This is a wrapper around plistlib.readPlist that tries to convert the
    plist to the XML format if it can't be parsed (assuming that it is in
    the binary format).

    Args:
      plist_path: string, path to a plist file, in XML or binary format

    Returns:
      Content of the plist as a dictionary.
    """
    try:
      # First, try to read the file using plistlib that only supports XML,
      # and if an exception is raised, convert a temporary copy to XML and
      # load that copy.
      return plistlib.readPlist(plist_path)
    except:
      pass
    with tempfile.NamedTemporaryFile() as temp:
      shutil.copy2(plist_path, temp.name)
      subprocess.check_call(['plutil', '-convert', 'xml1', temp.name])
      return plistlib.readPlist(temp.name)

  def _GetSubstitutions(self, bundle_identifier, app_identifier_prefix):
    """Constructs a dictionary of variable substitutions for Entitlements.plist.

    Args:
      bundle_identifier: string, value of CFBundleIdentifier from Info.plist
      app_identifier_prefix: string, value for AppIdentifierPrefix

    Returns:
      Dictionary of substitutions to apply when generating Entitlements.plist.
    """
    return {
      'CFBundleIdentifier': bundle_identifier,
      'AppIdentifierPrefix': app_identifier_prefix,
    }

  def _GetCFBundleIdentifier(self):
    """Extracts CFBundleIdentifier value from Info.plist in the bundle.

    Returns:
      Value of CFBundleIdentifier in the Info.plist located in the bundle.
    """
    info_plist_path = os.path.join(
        os.environ['TARGET_BUILD_DIR'],
        os.environ['INFOPLIST_PATH'])
    info_plist_data = self._LoadPlistMaybeBinary(info_plist_path)
    return info_plist_data['CFBundleIdentifier']

  def _InstallEntitlements(self, entitlements, substitutions, overrides):
    """Generates and install the ${BundleName}.xcent entitlements file.

    Expands variables "$(variable)" pattern in the source entitlements file,
    add extra entitlements defined in the .mobileprovision file and the copy
    the generated plist to "${BundlePath}.xcent".

    Args:
      entitlements: string, optional, path to the Entitlements.plist template
        to use, defaults to "${SDKROOT}/Entitlements.plist"
      substitutions: dictionary, variable substitutions
      overrides: dictionary, values to add to the entitlements

    Returns:
      Path to the generated entitlements file.
    """
    source_path = entitlements
    target_path = os.path.join(
        os.environ['BUILT_PRODUCTS_DIR'],
        os.environ['PRODUCT_NAME'] + '.xcent')
    if not source_path:
      source_path = os.path.join(
          os.environ['SDKROOT'],
          'Entitlements.plist')
    shutil.copy2(source_path, target_path)
    data = self._LoadPlistMaybeBinary(target_path)
    data = self._ExpandVariables(data, substitutions)
    if overrides:
      for key in overrides:
        if key not in data:
          data[key] = overrides[key]
    plistlib.writePlist(data, target_path)
    return target_path

  def _ExpandVariables(self, data, substitutions):
    """Expands variables "$(variable)" in data.

    Args:
      data: object, can be either string, list or dictionary
      substitutions: dictionary, variable substitutions to perform

    Returns:
      Copy of data where each references to "$(variable)" has been replaced
      by the corresponding value found in substitutions, or left intact if
      the key was not found.
    """
    if isinstance(data, str):
      for key, value in substitutions.iteritems():
        data = data.replace('$(%s)' % key, value)
      return data
    if isinstance(data, list):
      return [self._ExpandVariables(v, substitutions) for v in data]
    if isinstance(data, dict):
      return {k: self._ExpandVariables(data[k], substitutions) for k in data}
    return data

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