#!/usr/bin/env python

import subprocess
import re
import os
import errno
import collections
import sys

class Platform(object):
    pass

sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)')

def sdkinfo(sdkname):
    ret = {}
    for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout:
        kv = line.strip().split(': ', 1)
        if len(kv) == 2:
            k,v = kv
            ret[k] = v
    return ret

sim_sdk_info = sdkinfo('iphonesimulator')
device_sdk_info = sdkinfo('iphoneos')

def latest_sdks():
    latest_sim = None
    latest_device = None
    for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout:
        match = sdk_re.match(line)
        if match:
            if 'Simulator' in line:
                latest_sim = match.group(1)
            elif 'iOS' in line:
                latest_device = match.group(1)

    return latest_sim, latest_device

sim_sdk, device_sdk = latest_sdks()

class simulator_platform(Platform):
    sdk='iphonesimulator'
    arch = 'i386'
    name = 'simulator'
    triple = 'i386-apple-darwin10'
    sdkroot = sim_sdk_info['Path']

    prefix = "#if !defined(__arm__) && defined(__i386__)\n\n"
    suffix = "\n\n#endif"

class device_platform(Platform):
    sdk='iphoneos'
    name = 'ios'
    arch = 'armv7'
    triple = 'arm-apple-darwin10'
    sdkroot = device_sdk_info['Path']

    prefix = "#ifdef __arm__\n\n"
    suffix = "\n\n#endif"


def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''):
    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)

    out_filename = filename

    if file_suffix:
        split_name = os.path.splitext(filename)
        out_filename =  "%s_%s%s" % (split_name[0], file_suffix, split_name[1])

    with open(os.path.join(src_dir, filename)) as in_file:
        with open(os.path.join(dst_dir, out_filename), 'w') as out_file:
            if prefix:
                out_file.write(prefix)

            out_file.write(in_file.read())

            if suffix:
                out_file.write(suffix)

headers_seen = collections.defaultdict(set)

def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None):
    for root, dirs, files in os.walk(src_dir, followlinks=True):
        relroot = os.path.relpath(root,src_dir)

        def move_dir(arch, prefix='', suffix='', files=[]):
            for file in files:
                file_suffix = None
                if file.endswith('.h'):
                    if dest_include_dir:
                        file_suffix = arch
                        if arch:
                            headers_seen[file].add(arch)
                        move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix)

                elif dest_dir:
                    outroot = os.path.join(dest_dir, relroot)
                    move_file(root, outroot, file, prefix=prefix, suffix=suffix)

        if relroot == '.':
            move_dir(arch=arch,
                     files=files,
                     prefix=prefix,
                     suffix=suffix)
        elif relroot == 'arm':
            move_dir(arch='arm',
                     prefix="#ifdef __arm__\n\n",
                     suffix="\n\n#endif",
                     files=files)
        elif relroot == 'x86':
            move_dir(arch='i386',
                     prefix="#if !defined(__arm__) && defined(__i386__)\n\n",
                     suffix="\n\n#endif",
                     files=files)

def build_target(platform):
    def xcrun_cmd(cmd):
        return subprocess.check_output(['xcrun', '-sdk', platform.sdkroot, '-find', cmd]).strip()

    build_dir = 'build_' + platform.name
    if not os.path.exists(build_dir):
        os.makedirs(build_dir)
        env = dict(CC=xcrun_cmd('clang'),
                   LD=xcrun_cmd('ld'),
                   CFLAGS='-arch %s -isysroot %s -miphoneos-version-min=4.0' % (platform.arch, platform.sdkroot))
        working_dir=os.getcwd()
        try:
            os.chdir(build_dir)
            subprocess.check_call(['../configure', '-host', platform.triple], env=env)
            move_source_tree('.', None, '../ios/include',
                             arch=platform.arch,
                             prefix=platform.prefix,
                             suffix=platform.suffix)
            move_source_tree('./include', None, '../ios/include',
                            arch=platform.arch,
                            prefix=platform.prefix,
                            suffix=platform.suffix)
        finally:
            os.chdir(working_dir)

        for header_name, archs in headers_seen.iteritems():
            basename, suffix = os.path.splitext(header_name)

def main():
    move_source_tree('src', 'ios/src', 'ios/include')
    move_source_tree('include', None, 'ios/include')
    build_target(simulator_platform)
    build_target(device_platform)

    for header_name, archs in headers_seen.iteritems():
        basename, suffix = os.path.splitext(header_name)
        with open(os.path.join('ios/include', header_name), 'w') as header:
            for arch in archs:
                header.write('#include <%s_%s%s>\n' % (basename, arch, suffix))

if __name__ == '__main__':
    main()
