# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
Finds the team identifier to use for code signing bundle given its
bundle identifier.
"""

import argparse
import fnmatch
import glob
import json
import os
import plistlib
import subprocess
import sys


class ProvisioningProfile(object):

  def __init__(self, mobileprovision_path):
    self._path = mobileprovision_path
    self._data = plistlib.readPlistFromString(
        subprocess.check_output(
            ['security', 'cms', '-D', '-i', mobileprovision_path]))

  @property
  def application_identifier_pattern(self):
    return self._data.get('Entitlements', {}).get('application-identifier', '')

  @property
  def app_identifier_prefix(self):
    return self._data.get('ApplicationIdentifierPrefix', [''])[0]

  def ValidToSignBundle(self, bundle_identifier):
    """Returns whether the provisioning profile can sign |bundle_identifier|."""
    return fnmatch.fnmatch(
        self.app_identifier_prefix + '.' + bundle_identifier,
        self.application_identifier_pattern)


def GetProvisioningProfilesDir():
  """Returns the location of the locally installed provisioning profiles."""
  return os.path.join(
      os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles')


def ListProvisioningProfiles():
  """Returns a list of all installed provisioning profiles."""
  return glob.glob(
      os.path.join(GetProvisioningProfilesDir(), '*.mobileprovision'))


def LoadProvisioningProfile(mobileprovision_path):
  """Loads the Apple Property List embedded in |mobileprovision_path|."""
  return ProvisioningProfile(mobileprovision_path)


def ListValidProvisioningProfiles(bundle_identifier):
  """Returns a list of provisioning profile valid for |bundle_identifier|."""
  result = []
  for mobileprovision_path in ListProvisioningProfiles():
    mobileprovision = LoadProvisioningProfile(mobileprovision_path)
    if mobileprovision.ValidToSignBundle(bundle_identifier):
      result.append(mobileprovision)
  return result


def FindProvisioningProfile(bundle_identifier):
  """Returns the path to the provisioning profile for |bundle_identifier|."""
  return max(
      ListValidProvisioningProfiles(bundle_identifier),
      key=lambda p: len(p.application_identifier_pattern))


def GenerateSubsitutions(bundle_identifier, mobileprovision):
  if mobileprovision:
    app_identifier_prefix = mobileprovision.app_identifier_prefix + '.'
  else:
    app_identifier_prefix = '*.'

  return {
      'CFBundleIdentifier': bundle_identifier,
      'AppIdentifierPrefix': app_identifier_prefix
  }


def ParseArgs(argv):
  """Parses command line arguments."""
  parser = argparse.ArgumentParser(
      description=__doc__,
      formatter_class=argparse.ArgumentDefaultsHelpFormatter)

  parser.add_argument(
      '-b', '--bundle-identifier', required=True,
      help='bundle identifier for the application')
  parser.add_argument(
      '-o', '--output', default='-',
      help='path to the result; - means stdout')

  return parser.parse_args(argv)


def main(argv):
  args = ParseArgs(argv)

  mobileprovision = FindProvisioningProfile(args.bundle_identifier)
  substitutions = GenerateSubsitutions(args.bundle_identifier, mobileprovision)

  if args.output == '-':
    sys.stdout.write(json.dumps(substitutions))
  else:
    with open(args.output, 'w') as output:
      output.write(json.dumps(substitutions))


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