#!/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

desktop_sdk_info = sdkinfo('macosx')

def latest_sdks():
    latest_desktop = None
    for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout:
        match = sdk_re.match(line)
        if match:
            if 'OS X' in line:
                latest_desktop = match.group(1)

    return latest_desktop

desktop_sdk = latest_sdks()

class desktop_platform_32(Platform):
    sdk='macosx'
    arch = 'i386'
    name = 'mac32'
    triple = 'i386-apple-darwin10'
    sdkroot = desktop_sdk_info['Path']
    
    prefix = "#if defined(__i386__) && !defined(__x86_64__)\n\n"
    suffix = "\n\n#endif"

class desktop_platform_64(Platform):
    sdk='macosx'
    arch = 'x86_64'
    name = 'mac'
    triple = 'x86_64-apple-darwin10'
    sdkroot = desktop_sdk_info['Path']
    
    prefix = "#if !defined(__i386__) && defined(__x86_64__)\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 == 'x86':
            move_dir(arch='i386',
                     prefix="#if defined(__i386__) && !defined(__x86_64__)\n\n",
                     suffix="\n\n#endif",
                     files=files)
            move_dir(arch='x86_64',
                     prefix="#if !defined(__i386__) && defined(__x86_64__)\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 -mmacosx-version-min=10.6' % (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, '../osx/include',
                             arch=platform.arch,
                             prefix=platform.prefix,
                             suffix=platform.suffix)
            move_source_tree('./include', None, '../osx/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', 'osx/src', 'osx/include')
    move_source_tree('include', None, 'osx/include')
    build_target(desktop_platform_32)
    build_target(desktop_platform_64)

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

if __name__ == '__main__':
    main()
