import file_utils
import xml_utils
import os.path

def changeApplication(game, sdk, subChannel, config, targetApplication):
    '''
    修改最顶级的application
    '''

    decompliePath = file_utils.getDecompliePath(game, sdk, subChannel, config['cache'])
    manifest = os.path.join(decompliePath, 'AndroidManifest.xml')
    application = xml_utils.getApplicationAttr(manifest, 'name')

    if application is None:
        xml_utils.changeApplicationAttr(manifest, 'name', targetApplication)

        print('change add application %s' % targetApplication)
    else:
        smaliPath = os.path.join(decompliePath, 'smali')
        superApplication = findSuperApplication(smaliPath, application)
        print('super application is %s' % superApplication)

        if superApplication == targetApplication:
            return
        changeSuperApplication(smaliPath, superApplication, targetApplication.replace('.', '/'))

        print('change super application %s to %s' % (superApplication, targetApplication))

def findSuperApplication(basePath, className):
    '''
    获取最顶级的application
    '''
    tagSuper = '.super Landroid/app/Application;'
    tag = '.super L'
    applicationFile = file_utils.getPackagePath(basePath, className) + '.smali'

    topClassName = None
    superClass = None
    with openFile(applicationFile, 'r') as f:
        line = f.readline()

        while line:
            if tagSuper in line:
                topClassName = className
                break
            elif tag in line:
                superClass = line[8:-2]
                superClass = superClass.replace('/', '.')
                break
                
            line = f.readline()

    if topClassName is not None:
        return topClassName
    elif superClass is not None:
        return findSuperApplication(basePath, superClass)

def changeSuperApplication(basePath, className, targetApplication):
    '''
    更改application
    '''
    applicationFile = file_utils.getPackagePath(basePath, className) + '.smali'

    # 修改application
    changeSuperApplicationSmali(applicationFile, targetApplication)

def changeSuperApplicationSmali(file, application):
    '''
    修改application.smali
    '''
    contentSpuer = '.super Landroid/app/Application;'
    constructor = '.method public constructor <init>()V'
    direct = 'invoke-direct'
    invokeSuper = 'invoke-super'
    applicationTag = 'Landroid/app/Application;->'
    newContent = ''

    with openFile(file, 'r+') as f:
        line = f.readline()
        isConstructor = False

        while line:
            if contentSpuer in line:
                newContent += '.super L%s;\n' % application
            elif invokeSuper in line and applicationTag in line:
                newContent += line.replace('android/app/Application', application)
            elif isConstructor and direct in line and applicationTag in line:
                newContent += line.replace('android/app/Application', application)
                isConstructor = False
            else:
                if constructor in line:
                    isConstructor = True
                newContent += line

            line = f.readline()

        f.seek(0, 0)
        #清空内容
        f.truncate()
        f.write(newContent)
    return 0

def openFile(file, mode):
    return file_utils.openFile(file, mode)