#!/usr/bin/env python

import argparse
from isign import isign
from os.path import abspath, expanduser
import logging

FORMATTER = logging.Formatter('%(message)s')


def log_to_stderr(level=logging.INFO):
    root = logging.getLogger()
    root.setLevel(level)
    handler = logging.StreamHandler()
    handler.setFormatter(FORMATTER)
    root.addHandler(handler)


def absolute_path_argument(path):
    return abspath(expanduser(path))


def parse_args():
    # note that for arguments which eventually get fed into
    # isign.resign, we deliberately don't set defaults. The kwarg
    # defaults in isign.resign will be used
    parser = argparse.ArgumentParser(
        description='Resign an iOS application with a new identity '
                    'and provisioning profile.')
    parser.add_argument(
        '-p', '--provisioning-profile',
        dest='provisioning_profile',
        required=False,
        metavar='<your.mobileprovision path>',
        type=absolute_path_argument,
        help='Path to provisioning profile'
    )
    parser.add_argument(
        '-a', '--apple-cert',
        dest='apple_cert',
        required=False,
        metavar='<apple cert>',
        type=absolute_path_argument,
        help='Path to Apple certificate in .pem form'
    )
    parser.add_argument(
        '-k', '--key',
        dest='key',
        required=False,
        metavar='<key path>',
        type=absolute_path_argument,
        help='Path to your organization\'s key in .p12 format'
    )
    parser.add_argument(
        '-c', '--certificate',
        dest='certificate',
        required=False,
        metavar='<certificate path>',
        type=absolute_path_argument,
        help='Path to your organization\'s certificate in .pem form'
    )
    parser.add_argument(
        '-o', '--output',
        dest='output_path',
        required=False,
        metavar='<output path>',
        type=absolute_path_argument,
        help='Path to output file or directory'
    )
    parser.add_argument(
        'app_paths',
        nargs=1,
        metavar='<app path>',
        type=absolute_path_argument,
        help='Path to application to re-sign, typically a '
             'directory ending in .app or file ending in .ipa.'
    )
    parser.add_argument(
        '-v', '--verbose',
        dest='verbose',
        action='store_true',
        default=False,
        required=False,
        help='Set logging level to debug.'
    )
    parser.add_argument(
        '-i', '--info',
        dest='info_props',
        required=False,
        metavar='<Info.plist properties>',
        help='List of comma-delimited key=value pairs of Info.plist properties to override'
    )
    return parser.parse_args()


if __name__ == '__main__':
    args = parse_args()

    if args.verbose:
        level = logging.DEBUG
    else:
        level = logging.INFO
    log_to_stderr(level)

    # Filter out args that don't matter to the
    # resign call, like verbosity or help
    resign_args = ['certificate',
                   'key',
                   'apple_cert',
                   'provisioning_profile',
                   'output_path']
    kwargs = {}
    # we want the unused command line args to be
    # missing in kwargs, so the defaults are used
    for k, v in vars(args).iteritems():
        if k in resign_args and v is not None:
            kwargs[k] = v

    # Convert the Info.plist property pairs to a dict format
    if args.info_props:
        info_props = {}
        for arg in args.info_props.split(','):
            i = arg.find('=')
            if i < 0:
                raise Exception('Invalid Info.plist argument: ' + arg)
            info_props[arg[0:i]] = arg[i + 1:]
        if info_props:
            kwargs['info_props'] = info_props

    isign.resign(args.app_paths[0], **kwargs)
