import file_utils
import config_utils
import sys
import os.path
import json

def packageChannel():
    if len(sys.argv) < 2:
        print('argument is missing')
        return 1

    channelConfig = sys.argv[1]

    jsonText = file_utils.readFile(channelConfig)
    config = json.loads(jsonText)

    print('*************config*****************')
    print(jsonText)
    print('************************************')

    # 检查配置
    if not checkConfig(config):
        return 1

    # 检查文件
    gameApk = config['package']
    if not os.path.exists(gameApk):
        print('%s not exists' % gameApk)

    if supportSignV2(gameApk):
        packageChannelV2(gameApk, config)
    else:
        packageChannelV1(gameApk, config)

def supportSignV2(gameApk):
    '''
    验证是否APK Signature Scheme v2
    '''
    apksigner = file_utils.getApksignerPath()
    ret = getJavaResult(apksigner, 'verify --verbose "%s"' % gameApk)

    if '(APK Signature Scheme v2): true' in ret:
        return True
    return False

def packageChannelV2(gameApk, config):
    walle = file_utils.getWallePath()

    if not os.path.exists(config['outPath']):
        os.makedirs(config['outPath'])

    successCount = 0
    failureCount = 0
    channels = config['channel']
    for channel in channels:
        signedApk = os.path.join(config['outPath'], channel['outName'] + '.apk')
        print('add channel package %s...' % signedApk)
        appid = ''
        appkey = ''
        version = config_utils.getDate()
        if 'appid' in channel:
            appid = channel['appid']
        if 'appkey' in channel:
            appkey = channel['appkey']
        if 'version' in channel:
            version = channel['version']
        ret = file_utils.execJarCmd(walle, 'put -e version=%s,agent=%s,appid=%s,appkey=%s "%s" "%s"' % (version, channel['agent'], appid, appkey, gameApk, signedApk))
        if ret:
            failureCount += 1
        else:
            successCount += 1

    print('success %d, failure %d' % (successCount, failureCount))

def packageChannelV1(gameApk, config):
    # 解包
    decompliePath = os.path.join(file_utils.getCurrentPath(), 'gen', 'channel')
    if os.path.exists(decompliePath):
        print('delete decomplie folder...')
        file_utils.deleteFolder(decompliePath)

    print('decomplie apk...')
    apktoolPath = file_utils.getApkToolPath()
    ret = file_utils.execJarCmd(apktoolPath, 'd -f "%s" -o "%s"' % (gameApk, decompliePath))
    if ret:
        return ret

    if not os.path.exists(config['outPath']):
        os.makedirs(config['outPath'])

    alignapkTool = file_utils.getAlignPath()
    apksigner = file_utils.getApksignerPath()
    path = os.path.join(file_utils.getCurrentPath(), 'keystore', 'key.json')
    jsonText = file_utils.readFile(path)
    signConfig = json.loads(jsonText)
    keystore = signConfig['default']
    storeFile = os.path.join(file_utils.getCurrentPath(), 'keystore', keystore['storeFile'])

    successCount = 0
    failureCount = 0
    channels = config['channel']
    
    for channel in channels:
        changeChannel(decompliePath, channel)

        temp = channel['agent']
        backApk = os.path.join(decompliePath, temp + '.apk')
        alignApk = os.path.join(decompliePath, temp + '_align.apk')
        signedApk = os.path.join(config['outPath'], channel['outName'] + '.apk')

        print('add channel package %s...' % signedApk)
        print('recomplie apk...')
        ret = file_utils.execJarCmd(apktoolPath, 'b -f "%s" -o "%s"' % (decompliePath, backApk))
        if ret:
            failureCount += 1
            continue

        print('align apk...')
        ret = file_utils.execFormatCmd('"%s" -f -p 4 "%s" "%s"' % (alignapkTool, backApk, alignApk))
        if ret:
            failureCount += 1
            continue

        print('sign apk...')
        ret = file_utils.execJarCmd(apksigner, 'sign --v2-signing-enabled=false --ks "%s" --ks-key-alias %s --ks-pass pass:%s --key-pass pass:%s --out "%s" "%s"' % (storeFile, keystore['keyAlias'], keystore['storePassword'], keystore['keyPassword'], signedApk, alignApk))
        if ret:
            failureCount += 1
        else:
            successCount += 1

        if os.path.exists(alignApk):
            os.remove(alignApk)
        if os.path.exists(backApk):
            os.remove(backApk)

    print('success %d, failure %d' % (successCount, failureCount))

def changeChannel(decompliePath, channel):
    '''
    修改渠道
    '''
    properties = os.path.join(decompliePath, 'assets', 'jmhy.properties')
    appid = ''
    appkey = ''
    version = config_utils.getDate()
    if 'appid' in channel:
        appid = channel['appid']
    if 'appkey' in channel:
        appkey = channel['appkey']
    if 'version' in channel:
        version = channel['version']
    content = 'version=%s\nagent=%s\nappid=%s\nappkey=%s' % (version, channel['agent'], appid, appkey)
    file_utils.createFile(properties, content)

def checkConfig(config):
    if 'package' not in config:
        print('package not exists in config')
        return False

    if 'outPath' not in config:
        print('outPath not exists in config')
        return False

    if 'channel' not in config:
        print('channel not exists in config')
        return False

    return True

def getJavaResult(jar, cmd):
    return getCmdResult('java -jar "%s" %s' % (jar, cmd))

def getCmdResult(cmd):
    p = os.popen(cmd)
    content = p.read()
    return content

packageChannel()