'''
    ios-s3-dist.py

    Python 3 Script to assist in distributing ad-hoc and enterprise iOS builds.
    Uploads build to S3 and creates a manifest.plist file to install it with.

    Required information should be profiled in a 'config.json' file.

    Usage:

        ios-dist.py {filename or path to build}

'''


def main(build_filename):

    import tinys3, json, os, plistlib, shutil, zipfile

    cnfg = json.load( open('config.json') )

    # ---- Get information from build's Info.plist

    zfile = zipfile.ZipFile(build_filename)

    for name in zfile.namelist():
        if name.endswith('Info.plist'):
            zfile.extract(name, 'temp')
            shutil.move('temp/'+name, 'temp/Info.plist')
            shutil.rmtree('temp/Payload')

    info = plistlib.load( open('temp/Info.plist', 'rb') )

    bundle_name       = info['CFBundleName']
    bundle_identifier = info['CFBundleIdentifier']
    bundle_version    = info['CFBundleVersion']


    # ---- Determine which build # this is by the number of existing builds

    conn = tinys3.Connection(cnfg['s3_access_key'], cnfg['s3_secret_key'])

    uploaded_builds = conn.list(
        'b/'+bundle_name+'-'+bundle_version,
        cnfg['bucket_name']
    )

    b_num = 1
    for x in uploaded_builds:
        b_num += 1

    build_number = 'b{0}'.format(b_num)


    # ---- Generate filenames from extracted information

    # Ex: 'AppName-2.0-b5.ipa'
    bd_filename = bundle_name+'-'+bundle_version+'-'+build_number+'.ipa'

    # Ex: 'manifest-2.0-b5.plist'
    mn_filename = 'manifest-'+bundle_version+'-'+build_number+'.plist'


    # ---- Create manifest.plist file from template
    #   {0} - URL to .ipa
    #   {1} - Bundle identifier
    #   {2} - Bundle version
    #   {3} - Bundle name

    template_file = open('manifest-template', 'r')

    manifest_data = template_file.read().format(
        'https://s3.amazonaws.com/'+cnfg['bucket_name']+'/b/'+bd_filename,
        bundle_identifier,
        bundle_version,
        bundle_name
    )
    template_file.close()

    manifest_file = open('temp/manifest.plist', 'w')
    manifest_file.write(manifest_data)
    manifest_file.close()


    # ---- Upload build and manifest to S3

    print('\nUploading build...')

    build_file = open(build_filename, 'rb')
    r = conn.upload(bd_filename, build_file, cnfg['bucket_name']+'/b')

    if r.status_code != 200:
        print('Error: Build upload unsuccessful (Status code {0)'\
            .format(r.status_code))
        shutil.rmtree('temp')
        return

    print('Uploading manifest...')

    manifest_file = open('temp/manifest.plist', 'rb')
    r = conn.upload(mn_filename, manifest_file, cnfg['bucket_name']+'/m')

    if r.status_code != 200:
        print('Error: Manifest upload unsuccessful (Status code {0)'\
            .format(r.status_code))
        # Try to clean up
        conn.delete(bd_filename, cnfg['bucket_name']+'/b')
        shutil.rmtree('temp')
        return


    # ---- Clean up and finish

    shutil.rmtree('temp')

    print('\nUpload successful! ({0})\n'.format(bd_filename))

    aws = 'https://s3.amazonaws.com/'
    b_url = aws+cnfg['bucket_name']+'/b/'+bd_filename
    m_url = aws+cnfg['bucket_name']+'/m/'+mn_filename

    print('-'*32)
    print('Build    : {0}'.format(b_url))
    print('Manifest : {0}'.format(m_url))

    itms = '\nitms-services://?action=download-manifest&url={0}'
    print(itms.format(m_url))
    print('-'*32+'\n')


if __name__ == '__main__':

    import sys

    if len(sys.argv) == 2:
        build_path = sys.argv[1]
        main(build_path)
    else:
        print('\nUsage:\n\tios-dist.py {filename or path to build}\n')

