#!/usr/bin/env python3

# Copyright (c) 2012 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.

#
# Xcode supports build variable substitutions and CPP; sadly, that doesn't work
# because:
#
# 1. Xcode wants to do the Info.plist work before it runs any build phases,
#    this means if we were to generate a .h file for INFOPLIST_PREFIX_HEADER
#    we'd have to put it in another target so it runs in time.
# 2. Xcode also doesn't check to see if the header being used as a prefix for
#    the Info.plist has changed.  So even if we updated it, it's only looking
#    at the modtime of the info.plist to see if that's changed.
#
# So, we work around all of this by making a script build phase that will run
# during the app build, and simply update the info.plist in place.  This way
# by the time the app target is done, the info.plist is correct.
#

import optparse
import os
from os import environ as env
import plistlib
import re
import subprocess
import sys
import tempfile

TOP = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))


def _GetOutput(args):
    """Runs a subprocess and waits for termination. Returns (stdout, returncode)
  of the process. stderr is attached to the parent."""
    proc = subprocess.Popen(args, stdout=subprocess.PIPE)
    (stdout, stderr) = proc.communicate()
    return (stdout, proc.returncode)


def _GetOutputNoError(args):
    """Similar to _GetOutput() but ignores stderr. If there's an error launching
  the child (like file not found), the exception will be caught and (None, 1)
  will be returned to mimic quiet failure."""
    try:
        proc = subprocess.Popen(
            args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    except OSError:
        return (None, 1)
    (stdout, stderr) = proc.communicate()
    return (stdout, proc.returncode)


def _RemoveKeys(plist, *keys):
    """Removes a varargs of keys from the plist."""
    for key in keys:
        try:
            del plist[key]
        except KeyError:
            pass


def _AddVersionKeys(plist, version=None):
    """Adds the product version number into the plist. Returns True on success and
  False on error. The error will be printed to stderr."""
    if version:
        match = re.match('\d+\.\d+\.(\d+\.\d+)$', version)
        if not match:
            print('Invalid version string specified: "%s"' % version,
                  file=sys.stderr)
            return False

        full_version = match.group(0)
        bundle_version = match.group(1)

    else:
        # Pull in the Chrome version number.
        VERSION_TOOL = os.path.join(TOP, 'build/util/version.py')
        VERSION_FILE = os.path.join(TOP, 'chrome/VERSION')

        (stdout, retval1) = _GetOutput([
            VERSION_TOOL, '-f', VERSION_FILE, '-t',
            '@MAJOR@.@MINOR@.@BUILD@.@PATCH@'
        ])
        full_version = stdout.rstrip()

        (stdout, retval2) = _GetOutput(
            [VERSION_TOOL, '-f', VERSION_FILE, '-t', '@BUILD@.@PATCH@'])
        bundle_version = stdout.rstrip()

        # If either of the two version commands finished with non-zero returncode,
        # report the error up.
        if retval1 or retval2:
            return False

    # Add public version info so "Get Info" works.
    plist['CFBundleShortVersionString'] = full_version

    # Honor the 429496.72.95 limit.  The maximum comes from splitting 2^32 - 1
    # into  6, 2, 2 digits.  The limitation was present in Tiger, but it could
    # have been fixed in later OS release, but hasn't been tested (it's easy
    # enough to find out with "lsregister -dump).
    # http://lists.apple.com/archives/carbon-dev/2006/Jun/msg00139.html
    # BUILD will always be an increasing value, so BUILD_PATH gives us something
    # unique that meetings what LS wants.
    plist['CFBundleVersion'] = bundle_version

    # Return with no error.
    return True


def _DoSCMKeys(plist, add_keys):
    """Adds the SCM information, visible in about:version, to property list. If
  |add_keys| is True, it will insert the keys, otherwise it will remove them."""
    scm_revision = None
    if add_keys:
        # Pull in the Chrome revision number.
        VERSION_TOOL = os.path.join(TOP, 'build/util/version.py')
        LASTCHANGE_FILE = os.path.join(TOP, 'build/util/LASTCHANGE')
        (stdout, retval) = _GetOutput(
            [VERSION_TOOL, '-f', LASTCHANGE_FILE, '-t', '@LASTCHANGE@'])
        if retval:
            return False
        scm_revision = stdout.rstrip()

    # See if the operation failed.
    _RemoveKeys(plist, 'SCMRevision')
    if scm_revision != None:
        plist['SCMRevision'] = scm_revision
    elif add_keys:
        print('Could not determine SCM revision.  This may be OK.',
              file=sys.stderr)

    return True


def _AddBreakpadKeys(plist, branding):
    """Adds the Breakpad keys. This must be called AFTER _AddVersionKeys() and
  also requires the |branding| argument."""
    plist['BreakpadReportInterval'] = '3600'  # Deliberately a string.
    plist['BreakpadProduct'] = '%s_Mac' % branding
    plist['BreakpadProductDisplay'] = branding
    plist['BreakpadVersion'] = plist['CFBundleShortVersionString']
    # These are both deliberately strings and not boolean.
    plist['BreakpadSendAndExit'] = 'YES'
    plist['BreakpadSkipConfirm'] = 'YES'


def _RemoveBreakpadKeys(plist):
    """Removes any set Breakpad keys."""
    _RemoveKeys(plist, 'BreakpadURL', 'BreakpadReportInterval',
                'BreakpadProduct', 'BreakpadProductDisplay', 'BreakpadVersion',
                'BreakpadSendAndExit', 'BreakpadSkipConfirm')


def _TagSuffixes():
    # Keep this list sorted in the order that tag suffix components are to
    # appear in a tag value. That is to say, it should be sorted per ASCII.
    components = ('32bit', 'full')
    assert tuple(sorted(components)) == components

    components_len = len(components)
    combinations = 1 << components_len
    tag_suffixes = []
    for combination in range(0, combinations):
        tag_suffix = ''
        for component_index in range(0, components_len):
            if combination & (1 << component_index):
                tag_suffix += '-' + components[component_index]
        tag_suffixes.append(tag_suffix)
    return tag_suffixes


def _AddKeystoneKeys(plist, bundle_identifier):
    """Adds the Keystone keys. This must be called AFTER _AddVersionKeys() and
  also requires the |bundle_identifier| argument (com.example.product)."""
    plist['KSVersion'] = plist['CFBundleShortVersionString']
    plist['KSProductID'] = bundle_identifier
    plist['KSUpdateURL'] = 'https://tools.google.com/service/update2'

    _RemoveKeys(plist, 'KSChannelID')
    for tag_suffix in _TagSuffixes():
        if tag_suffix:
            plist['KSChannelID' + tag_suffix] = tag_suffix


def _RemoveKeystoneKeys(plist):
    """Removes any set Keystone keys."""
    _RemoveKeys(plist, 'KSVersion', 'KSProductID', 'KSUpdateURL')

    tag_keys = []
    for tag_suffix in _TagSuffixes():
        tag_keys.append('KSChannelID' + tag_suffix)
    _RemoveKeys(plist, *tag_keys)


def Main(argv):
    parser = optparse.OptionParser('%prog [options]')
    parser.add_option(
        '--breakpad',
        dest='use_breakpad',
        action='store',
        type='int',
        default=False,
        help='Enable Breakpad [1 or 0]')
    parser.add_option(
        '--breakpad_uploads',
        dest='breakpad_uploads',
        action='store',
        type='int',
        default=False,
        help='Enable Breakpad\'s uploading of crash dumps [1 or 0]')
    parser.add_option(
        '--keystone',
        dest='use_keystone',
        action='store',
        type='int',
        default=False,
        help='Enable Keystone [1 or 0]')
    parser.add_option(
        '--scm',
        dest='add_scm_info',
        action='store',
        type='int',
        default=True,
        help='Add SCM metadata [1 or 0]')
    parser.add_option(
        '--branding',
        dest='branding',
        action='store',
        type='string',
        default=None,
        help='The branding of the binary')
    parser.add_option(
        '--bundle_id',
        dest='bundle_identifier',
        action='store',
        type='string',
        default=None,
        help='The bundle id of the binary')
    parser.add_option(
        '--version',
        dest='version',
        action='store',
        type='string',
        default=None,
        help='The version string [major.minor.build.patch]')
    (options, args) = parser.parse_args(argv)

    if len(args) > 0:
        print(parser.get_usage(), file=sys.stderr)
        return 1

    # Read the plist into its parsed format.
    DEST_INFO_PLIST = os.path.join(env['TARGET_BUILD_DIR'],
                                   env['INFOPLIST_PATH'])
    plist = plistlib.readPlist(DEST_INFO_PLIST)

    # Insert the product version.
    if not _AddVersionKeys(plist, version=options.version):
        return 2

    # Add Breakpad if configured to do so.
    if options.use_breakpad:
        if options.branding is None:
            print('Use of Breakpad requires branding.', file=sys.stderr)
            return 1
        _AddBreakpadKeys(plist, options.branding)
        if options.breakpad_uploads:
            plist['BreakpadURL'] = 'https://clients2.google.com/cr/report'
        else:
            # This allows crash dumping to a file without uploading the
            # dump, for testing purposes.  Breakpad does not recognise
            # "none" as a special value, but this does stop crash dump
            # uploading from happening.  We need to specify something
            # because if "BreakpadURL" is not present, Breakpad will not
            # register its crash handler and no crash dumping will occur.
            plist['BreakpadURL'] = 'none'
    else:
        _RemoveBreakpadKeys(plist)

    # Only add Keystone in Release builds.
    if options.use_keystone and env['CONFIGURATION'] == 'Release':
        if options.bundle_identifier is None:
            print('Use of Keystone requires the bundle id.', file=sys.stderr)
            return 1
        _AddKeystoneKeys(plist, options.bundle_identifier)
    else:
        _RemoveKeystoneKeys(plist)

    # Adds or removes any SCM keys.
    if not _DoSCMKeys(plist, options.add_scm_info):
        return 3

    # Now that all keys have been mutated, rewrite the file.
    temp_info_plist = tempfile.NamedTemporaryFile()
    plistlib.writePlist(plist, temp_info_plist.name)

    # Info.plist will work perfectly well in any plist format, but traditionally
    # applications use xml1 for this, so convert it to ensure that it's valid.
    proc = subprocess.Popen([
        'plutil', '-convert', 'xml1', '-o', DEST_INFO_PLIST,
        temp_info_plist.name
    ])
    proc.wait()
    return proc.returncode


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