#!/usr/bin/env python

import sys, os.path
import plistlib
import shutil
from mod_pbxproj import XcodeProject

def process_app_controller_wrapper(filename, header, methodSignatures, valuesToAppend, positionsInMethod):

    appcontroller = open(filename, 'r')

    fileContent = appcontroller.read()
    ignoreIndicies = []
    for idx, val in enumerate(valuesToAppend):
        if val in fileContent:
            ignoreIndicies.append(idx)
    
    appcontroller.seek(0)
    lines = appcontroller.readlines()
    appcontroller.close()
    found = False    
    foundIndex = -1

    newContent = header
    for line in lines:

        if line.strip() == header.strip():
            continue         
        
        newContent += line
        for idx, val in enumerate(methodSignatures):
            if line.strip() == val and idx not in ignoreIndicies:
                foundIndex = idx
                found = True
        if found :
            if positionsInMethod[foundIndex] == 'begin' and line.strip() == '{':
                newContent += (valuesToAppend[foundIndex] + "\n")
                found = False
            if  positionsInMethod[foundIndex] == 'end' and line.strip() == '}':
                newContent = newContent[:-3]
                newContent += (valuesToAppend[foundIndex] + "\n")
                newContent += "}\n"
                found = False                       
                            
    appcontroller = open(filename, 'w')    
    appcontroller.write(newContent)
    appcontroller.close()        

def getHockeyAuthentificationCode():

    return '''
    if([HockeyAppUnity handleOpenURL:url sourceApplication:sourceApplication annotation:annotation]){
        return YES;
    }'''

def getViewLoadedCallbackCode():

    return '''
    [HockeyAppUnity sendViewLoadedMessageToUnity];'''

def modifyAppController(filename):

    header = importHeader()
    methodSignatures = []
    valueToAppend = []
    positionsInMethod = []

    methodSignatures.append('- (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation')
    valueToAppend.append(getHockeyAuthentificationCode())
    positionsInMethod.append("begin")

    if not appControllerCategoryExists:
        methodSignatures.append('- (void)showGameUI:(UIWindow*)window')
        valueToAppend.append(getViewLoadedCallbackCode())
        positionsInMethod.append("end")

    process_app_controller_wrapper(filename, header, methodSignatures, valueToAppend, positionsInMethod)    

def modifyAppControllerCategory(filename):

    header = importHeader()
    methodSignatures = []
    valueToAppend = []
    positionsInMethod = []
    
    methodSignatures.append('- (void)showGameUI')
    valueToAppend.append(getViewLoadedCallbackCode())
    positionsInMethod.append("end")

    process_app_controller_wrapper(filename, header, methodSignatures, valueToAppend, positionsInMethod)   

def importHeader():

    return '#import "HockeyAppUnity.h"\n'

def modifyUrlSchemes(info_plist_path, appID):

    plist = plistlib.readPlist(info_plist_path)

    new_settings = {
        "CFBundleURLSchemes": ["ha" + appID]
    }
    if "CFBundleURLTypes" in plist:

        found = False
        for entry in plist["CFBundleURLTypes"]:
            if entry == new_settings:
                found = True
                break

        if not found:
            plist["CFBundleURLTypes"].extend(new_settings)
    else:
        plist["CFBundleURLTypes"] = [new_settings]

    plistlib.writePlist(plist, info_plist_path)

def addFrameworks(project):

    framework_group = project.get_or_create_group('Frameworks')
    project.add_file_if_doesnt_exist('System/Library/Frameworks/Security.framework', tree='SDKROOT', weak=True, parent=framework_group)
    project.add_file_if_doesnt_exist('System/Library/Frameworks/CoreText.framework', tree='SDKROOT', weak=True, parent=framework_group)
    project.add_file_if_doesnt_exist('System/Library/Frameworks/AssetsLibrary.framework', tree='SDKROOT', weak=True, parent=framework_group)
    project.add_file_if_doesnt_exist('System/Library/Frameworks/QuickLook.framework', tree='SDKROOT', weak=True, parent=framework_group)
    project.add_file_if_doesnt_exist('System/Library/Frameworks/MobileCoreServices.framework', tree='SDKROOT', weak=True, parent=framework_group)

def addAdditionalFiles(assets_path, install_path, project):

    library_group = project.get_or_create_group('Libraries')
    srcFilePath = assets_path + '/Plugins/iOS/HockeySDKResources.bundle'
    dstFilePath = install_path + '/Libraries/HockeySDKResources.bundle'
    copyDirectory(srcFilePath, dstFilePath)
    project.add_file_if_doesnt_exist(dstFilePath, parent=library_group)
    
    classes_group = project.get_or_create_group('Classes')
    srcFilePath = assets_path + '/Plugins/iOS/HockeyAppUnity.h'
    dstFilePath = install_path + '/Classes/HockeyAppUnity.h'
    copyFile(srcFilePath, dstFilePath) 
    project.add_file_if_doesnt_exist(dstFilePath, parent=classes_group) 

def getAssetsPath(source_path):

    path_elements = source_path.split('/')
    assets_path = ''
    for item in path_elements[1:-2]:
        assets_path = assets_path +'/' + item

    return assets_path

def copyDirectory(srcPath, dstPath):
    try:
        shutil.copytree(srcPath, dstPath)
    except shutil.Error as e:
        print('Directory not copied. Error: %s' % e)
    except OSError as e:
        print('Directory not copied. Error: %s' % e)

def copyFile(srcPath, dstPath):
    try:
        shutil.copyfile(srcPath, dstPath) 
    except shutil.Error as e:
        print('File not copied. Error: %s' % e)
    except OSError as e:
        print('File not copied. Error: %s' % e)

source_path = sys.argv[0]
install_path = sys.argv[1]
target_platform = sys.argv[2]

# replace YOUR-APP-ID with the app ID provided by HockeyApp
appID = 'YOUR-APP-ID'

if target_platform != "iPhone": sys.exit()

pbxproj_path = os.path.join(install_path, 'Unity-iPhone.xcodeproj/project.pbxproj')
project = XcodeProject.Load(pbxproj_path)

info_plist_path = os.path.join(install_path, 'Info.plist')
modifyUrlSchemes(info_plist_path, appID)

addFrameworks(project)

assets_path = getAssetsPath(source_path)
addAdditionalFiles(assets_path, install_path, project)

category_path = install_path + '/Classes/UI/UnityAppController+ViewHandling.mm'
appControllerCategoryExists = os.path.exists(category_path)
if appControllerCategoryExists:
    modifyAppControllerCategory(category_path)

controller_path = install_path + '/Classes/UnityAppController.mm'
modifyAppController(controller_path)

if project.modified:
  project.backup()
  project.saveFormat3_2() #IMPORTANT, DONT USE THE OLD VERSION!