import time

from flask import Flask, request
import requests
from PIL import ImageFile, Image
import os
import shutil
import subprocess
from zipfile import ZipFile

ImageFile.SAFEBLOCK = 2048 * 2048

app = Flask(__name__)
# app.base_project = "/apps/3ps/build_apk/QmeraLite"
app.base_project = "/Users/easysoft/Documents/QmeraLite2"

# app.temp_folder = "/apps/3ps/build_apk/BuildApk"
app.temp_folder = "/Users/easysoft/BuildApk"
# app.apk_folder = "/var/www/html/palio.io/dashboardv2/uploads"
app.apk_folder = "/Users/easysoft/"
app.verbose = True
# app.ssl =('/etc/ssl/STAR_palio_io/STAR_palio_io.crt', '/etc/ssl/STAR_palio_io/STAR_palio_io.pem')
app.ssl = None
app.keytool = '/usr/bin/keytool'

app.base_project_name = os.path.basename(app.base_project)


def vprint(*data):
    if app.verbose:
        print(*data)


def create_folder(package_id):
    path = os.path.join(app.temp_folder, package_id)
    if not os.path.exists(path):
        os.mkdir(path)
    else:
        shutil.rmtree(path)
        os.mkdir(path)
    vprint(path)
    path_dest = os.path.join(path, app.base_project_name)
    if not os.path.exists(path_dest):
        shutil.copytree(app.base_project, path_dest)
    code_path = "app/src/main/java/"
    orig_code = "com/example/qmeralitesamplecode"
    path_package_id = package_id.replace(".", "/")
    c_code_path = os.path.join(path_dest, code_path, path_package_id)
    orig_code_path = os.path.join(path_dest, code_path, orig_code)
    if not os.path.exists(c_code_path):
        shutil.copytree(orig_code_path, c_code_path)
        shutil.rmtree(orig_code_path)
    return path_dest, c_code_path


def change_acc(c_code_path, acc):
    main_activity = os.path.join(c_code_path, "MainActivity.java")
    with open(main_activity, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("***REPLACE***WITH***YOUR***QMERA***ACCOUNT***", acc)
    with open(main_activity, "w") as f:
        f.write(replaced)


def change_url(c_code_path, url):
    main_activity = os.path.join(c_code_path, "MainActivity.java")
    with open(main_activity, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("https://www.google.com", url)
    with open(main_activity, "w") as f:
        f.write(replaced)


def change_name(path_dest, name):
    manifest = os.path.join(path_dest, "app/src/main/AndroidManifest.xml")
    string_res = os.path.join(path_dest, "app/src/main/res/values/strings.xml")
    with open(manifest, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("NexilisLite", name)
    with open(manifest, "w") as f:
        f.write(replaced)
    with open(string_res, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("Nexilis Sport", name)
    with open(string_res, "w") as f:
        f.write(replaced)

def change_font(path_dest, font, package):
    if font == 1:
        path_package_id = package.replace(".", "/")
        code_path = "app/src/main/java/"
        code_path = os.path.join(path_dest, code_path, path_package_id)
        res_path = "app/src/main/res/"
        res_path = os.path.join(path_dest, res_path)
        javas = [os.path.join(dp, f) for dp, dn, filenames in os.walk(code_path) for f in filenames]
        res = [os.path.join(dp, f) for dp, dn, filenames in os.walk(res_path) for f in filenames if "xml" in f]
        button_apps_code_path = os.path.join(path_dest, "palio-button-app/src/main/java")
        button_apps_res_path = os.path.join(path_dest, "palio-button-app/src/main/res-pba/")
        lib_javas = [os.path.join(dp, f) for dp, dn, filenames in os.walk(button_apps_code_path) for f in filenames]
        lib_res = [os.path.join(dp, f) for dp, dn, filenames in os.walk(button_apps_res_path) for f in filenames if "xml" in f]
        for j in javas:
            print(j)
            if "ForumFragment.java" in j:
                with open(j, "r") as f:
                    file_source = f.read()
                replaced = file_source.replace("pb_poppins", "roboto")
                with open(j, "w") as f:
                    f.write(replaced)
        for j in res:
            print(j)
            with open(j, "r") as f:
                file_source = f.read()
            replaced = file_source.replace("pb_poppins", "roboto")
            with open(j, "w") as f:
                f.write(replaced)
        for j in lib_javas:
            print(j)
            with open(j, "r") as f:
                file_source = f.read()
            replaced = file_source.replace("pb_poppins", "roboto")
            with open(j, "w") as f:
                f.write(replaced)
        for j in lib_res:
            print(j)
            with open(j, "r") as f:
                file_source = f.read()
            replaced = file_source.replace("pb_poppins", "roboto")
            with open(j, "w") as f:
                f.write(replaced)


def change_package(path_dest, package):
    build_gradle = os.path.join(path_dest, 'app/build.gradle')
    with open(build_gradle, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("com.example.qmeralitesamplecode", package)
    with open(build_gradle, "w") as f:
        f.write(replaced)
    proguard = os.path.join(path_dest, 'app/proguard-rules.pro')
    with open(proguard, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("com.example.qmeralitesamplecode", package)
    with open(proguard, "w") as f:
        f.write(replaced)
    manifest = os.path.join(path_dest, "app/src/main/AndroidManifest.xml")
    with open(manifest, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("com.example.qmeralitesamplecode", package)
    with open(manifest, "w") as f:
        f.write(replaced)
    path_package_id = package.replace(".", "/")
    code_path = "app/src/main/java/"
    code_path = os.path.join(path_dest, code_path, path_package_id)
    res_path = "app/src/main/res/"
    res_path = os.path.join(path_dest, res_path)
    javas = [os.path.join(dp, f) for dp, dn, filenames in os.walk(code_path) for f in filenames]
    res = [os.path.join(dp, f) for dp, dn, filenames in os.walk(res_path) for f in filenames if "xml" in f]
    for j in javas:
        print(j)
        with open(j, "r") as f:
            file_source = f.read()
        replaced = file_source.replace("com.example.qmeralitesamplecode", package)
        with open(j, "w") as f:
            f.write(replaced)
    for j in res:
        print(j)
        with open(j, "r") as f:
            file_source = f.read()
        replaced = file_source.replace("com.example.qmeralitesamplecode", package)
        with open(j, "w") as f:
            f.write(replaced)


def change_logo(path_dest, logo, logo_float=None):
    img_path = "app/src/main/res/drawable/ic_launcher.png"
    img_path = os.path.join(path_dest, img_path)
    img_notif = "app/src/main/res/drawable-v24/pb_ball.png"
    img_notif = os.path.join(path_dest, img_notif)
    img_path_float = "app/src/main/res/drawable/pb_button.png"
    img_path_float = os.path.join(path_dest, img_path_float)
    if isinstance(logo, str):
        logo = requests.get('https://newuniverse.io/dashboardv2/uploads/logo/{}'.format(logo))
        with open(img_path, "wb") as f:
            f.write(logo.content)
        with open(img_path, "rb") as f:
            logo = Image.open(f)
            logo = logo.resize((512, 512))
        if logo_float:
            logo_float = requests.get('https://newuniverse.io/dashboardv2/uploads/logofloat/{}'.format(logo_float))
            with open(img_path_float, "wb") as f:
                f.write(logo_float.content)
            with open(img_path_float, "rb") as f:
                logo_float = Image.open(f)
                logo_float = logo_float.resize((150, 150))
    else:
        logo = Image.open(logo)
        logo = logo.resize((512, 512))
        if logo_float:
            logo_float = Image.open(logo_float)
            logo_float = logo_float.resize((150, 150))
    logo.save(img_path, "PNG")
    if logo_float:
        logo_float.save(img_path_float, "PNG")
        logo_float.save(img_notif, "PNG")


def change_tab(path_dest, tabs, tab_icon, package, tab3_mode, tab_amount):
    default_tab_icon = ["tab1.png", "tab2.png", "tab3.png", "tab4.png"]
    for i in range(4):
        if not tab_icon[i]:
            continue
        img_path = "app/src/main/res/drawable-v24"
        img_path = os.path.join(path_dest, img_path, default_tab_icon[i])
        if isinstance(tab_icon[i], str):
            logo = requests.get('https://newuniverse.io/dashboardv2/uploads/tab_icon/{}'.format(tab_icon[i]))
            with open(img_path, "wb") as f:
                f.write(logo.content)
            with open(img_path, "rb") as f:
                logo = Image.open(f)
                logo = logo.resize((150, 150))
                logo.save(img_path, "PNG")
        else:
            logo = Image.open(tab_icon[i])
            logo = logo.resize((150, 150))
            logo.save(img_path, "PNG")
    path_package_id = package.replace(".", "/")
    code_path = "app/src/main/java/"
    sobj_code_path = os.path.join(path_dest, code_path, path_package_id, "SObj.java")
    print(sobj_code_path)
    with open(sobj_code_path, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("1,2,3,4", ",".join(tabs))
    with open(sobj_code_path, "w") as f:
        f.write(replaced)
    main_code_path = os.path.join(path_dest, code_path, path_package_id, "MainActivity.java")
    with open(main_code_path, "r") as f:
        file_source = f.read()
    replaced = file_source.replace('tab3 = "0"', 'tab3 = "{}"'.format(tab3_mode))
    with open(main_code_path, "w") as f:
        f.write(replaced)
    prefs_code_path = os.path.join(path_dest, code_path, path_package_id, "util/PrefsUtil.java")
    with open(prefs_code_path, "r") as f:
        file_source = f.read()
    replaced = file_source.replace('DEFAULT_TAB_AMOUNT = "4"', 'DEFAULT_TAB_AMOUNT = "{}"'.format(tab_amount))
    with open(prefs_code_path, "w") as f:
        f.write(replaced)

def change_fb(path_dest, fb_icon):
    default_fb_icon = ["pb_button_chat.png", "pb_button_call.png", "pb_button_cc.png", "pb_button_stream.png", "nexilis_fb_04.png"]
    for i in range(5):
        if not fb_icon[i]:
            continue
        img_path = "app/src/main/res/drawable-nodpi"
        img_path = os.path.join(path_dest, img_path, default_fb_icon[i])
        if isinstance(fb_icon[i], str):
            logo = requests.get('https://newuniverse.io/dashboardv2/uploads/fb_icon/{}'.format(fb_icon[i]))
            with open(img_path, "wb") as f:
                f.write(logo.content)
            with open(img_path, "rb") as f:
                logo = Image.open(f)
                logo = logo.resize((150, 150))
                logo.save(img_path, "PNG")
        else:
            logo = Image.open(fb_icon[i])
            logo = logo.resize((150, 150))
            logo.save(img_path, "PNG")


def change_background(path_dest, background):
    if isinstance(background, str):
        background = background.split(",")
        for i,b in enumerate(background):
            n = i+1
            img_path = "app/src/main/res/drawable-nodpi-v4/pb_lbackground_{}.png".format(n)
            img_path = os.path.join(path_dest, img_path)
            logo = requests.get('https://newuniverse.io/dashboardv2/uploads/background/{}'.format(b))
            with open(img_path, "wb") as f:
                f.write(logo.content)
            with open(img_path, "rb") as f:
                logo = Image.open(f)
                logo = logo.resize((600, 1250))
            logo.save(img_path, "PNG")
    else:
        img_path = "app/src/main/res/drawable-nodpi-v4/pb_lbackground_1.png"
        logo = Image.open(background)
        logo = logo.resize((600, 1250))
        logo.save(img_path, "PNG")


def change_access(path_dest, access_model, package):
    access = ["CPAAS_MODE_FLOATING", "CPAAS_MODE_DOCKED", "CPAAS_MODE_BURGER"]
    path_package_id = package.replace(".", "/")
    code_path = "app/src/main/java/"
    code_path = os.path.join(path_dest, code_path, path_package_id, "util", "PrefsUtil.java")
    print(code_path)
    with open(code_path, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("= CPAAS_MODE_DOCKED", "= {}".format(access[access_model]))
    with open(code_path, "w") as f:
        f.write(replaced)
    pass


def change_certificate(path_dest, key, keyfile, keytool):
    keyfile_name = "{}.keystore".format(key["alias"])
    keyfile_path = os.path.join(path_dest, keyfile_name)
    if keyfile:
        keyfile.save(keyfile_path)
    else:
        vprint("keytool run")
        os.chdir(path_dest)
        vprint("current working directory: ", os.getcwd())
        dname = "CN={}, OU={}, O={}, L={}, S={}, C={}".format(key["common_name"], key["organization_unit"],
                                                              key["organization_name"], key["locality_name"],
                                                              key["state_name"], key["country"])
        cmd = [keytool, "-genkey", "-v", "-keystore", keyfile_path, "-alias", key["alias"], "-keyalg", "RSA",
               "-keysize", "2048",
               "-validity", "10000", "-dname", dname, "-storepass", key["store_password"], "-keypass", key["key_password"]]
        vprint(cmd)
        subprocess.run(cmd)
        vprint("keytool end")
    build_gradle = os.path.join(path_dest, 'app/build.gradle')
    with open(build_gradle, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("allyourbase", key["store_password"])
    replaced = replaced.replace("arebelongto", key["key_password"])
    replaced = replaced.replace("key-qmeralite", key["alias"])
    with open(build_gradle, "w") as f:
        f.write(replaced)


def run_build(path_dest):
    gradlew = os.path.join(path_dest, "gradlew")
    ret = subprocess.run([gradlew, 'assembleRelease'])
    if ret.returncode == 0:
        ret = subprocess.run([gradlew, 'bundleRelease'])
    return ret.returncode


def deliver_apk(path_dest, package_id, key, key_exists):
    apk_dir = os.path.join(path_dest, 'app/build/outputs/apk/release/app-release.apk')
    aab_dir = os.path.join(path_dest, 'app/build/outputs/bundle/release/app-release.aab')
    keystore_name = '{}.keystore'.format(key["alias"])
    keystore_dir = os.path.join(path_dest, keystore_name)
    timenow = time.time()
    apk_name = "{}{}.apk".format(package_id, timenow)
    aab_name = "{}{}.aab".format(package_id, timenow)
    zip_name = "{}{}.zip".format(package_id, timenow)
    new_apk_dir = os.path.join(app.apk_folder, apk_name)
    new_aab_dir = os.path.join(app.apk_folder, aab_name)
    new_dir = os.path.join(app.apk_folder, zip_name)
    vprint(apk_dir)
    try:
        shutil.move(apk_dir, new_apk_dir)
        shutil.move(aab_dir, new_aab_dir)
        with ZipFile(new_dir, 'w') as zip_file:
            zip_file.write(new_apk_dir, os.path.basename(new_apk_dir))
            zip_file.write(new_aab_dir, os.path.basename(new_aab_dir))
            if not key_exists:
                zip_file.write(keystore_dir, os.path.basename(keystore_dir))
        os.remove(new_apk_dir)
        os.remove(new_aab_dir)
        project_path = os.path.join(app.temp_folder, package_id)
        shutil.rmtree(project_path)
        return {"name": zip_name}
    except Exception as e:
        return str(e)


def change_version(path_dest, version_code, version_name):
    build_gradle = os.path.join(path_dest, 'app/build.gradle')
    with open(build_gradle, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("versionCode 3", "versionCode {}".format(version_code))
    replaced = replaced.replace('versionName "3.0"', 'versionName "{}"'.format(version_name))
    with open(build_gradle, "w") as f:
        f.write(replaced)


@app.route('/', methods=["GET", "POST"])
def build_apk():
    vprint('==============================================================')
    if request.method == 'POST':
        logo = None
        logo_float = None
        app_name = "NexilisLite"
        package_id = "com.app.nexilis"
        acc = None
        url = None
        keystore = None
        key_exists = False
        # tabs = ["1", "2", "3", "4"]
        tabs = []
        tab3_mode = "0"
        tab_icon = [None, None, None, None]
        fb_icon = [None, None, None, None, None]
        background = None
        version_code = "1"
        version_name = "1.0.0"
        font = 0
        tab_amount = 4
        key = {"alias": "nexilislite", "store_password": "allyourbase", "key_password": "arebelongto", "common_name": "all", "organization_unit": "your",
               "organization_name": "base", "locality_name": "are", "state_name": "belong", "country": "to"}
        if 'logo' in request.files:
            logo = request.files['logo']
            vprint(type(logo))
        elif 'logo' in request.form:
            logo = request.form['logo']
            vprint(type(logo))
        if 'logofloat' in request.files:
            logo_float = request.files['logofloat']
            vprint(type(logo_float))
        elif 'logofloat' in request.form:
            logo_float = request.form['logofloat']
            vprint(type(logo_float))

        if 'app_name' in request.files:
            app_name = request.files['app_name']
            vprint(app_name)
        elif 'app_name' in request.form:
            app_name = request.form['app_name']
            vprint(app_name)

        if 'package_id' in request.files:
            package_id = request.files['package_id']
            vprint(package_id)
        elif 'package_id' in request.form:
            package_id = request.form['package_id']
            vprint(package_id)

        if 'acc' in request.files:
            acc = request.files['acc']
            vprint(acc)
        elif 'acc' in request.form:
            acc = request.form['acc']
            vprint(acc)

        if 'url' in request.files:
            url = request.files['url']
            vprint(url)
        elif 'url' in request.form:
            url = request.form['url']
            vprint(url)

        if 'keystore' in request.files:
            keystore = request.files['keystore']
            key_exists = True
        elif 'keystore' in request.form:
            keystore = request.form['keystore']
            key_exists = True

        if 'alias' in request.form:
            if request.form['alias']:
                key["alias"] = request.form['alias']
        if 'store_password' in request.form:
            if request.form['store_password']:
                key["store_password"] = request.form['store_password']
        if 'key_password' in request.form:
            if request.form['key_password']:
                key["key_password"] = request.form['key_password']
        if keystore:
            if 'common_name' in request.form:
                if request.form['common_name']:
                    key["common_name"] = request.form['common_name']
            if 'organization_unit' in request.form:
                if request.form['organization_unit']:
                    key["organization_unit"] = request.form['organization_unit']
            if 'organization_name' in request.form:
                if request.form['organization_name']:
                    key["organization_name"] = request.form['organization_name']
            if 'locality_name' in request.form:
                if request.form['locality_name']:
                    key["locality_name"] = request.form['locality_name']
            if 'state_name' in request.form:
                if request.form['state_name']:
                    key["state_name"] = request.form['state_name']
            if 'country' in request.form:
                if request.form['country']:
                    key["country"] = request.form['country']
        tabs.append(request.form["tab1"])
        tabs.append(request.form["tab2"])
        if request.form['tab3']:
            tabs.append(request.form["tab3"])
        if request.form['tab4']:
            tabs.append(request.form["tab4"])
        if 'tab1_icon' in request.files:
            tab_icon[0] = request.files['tab1_icon']
        elif 'tab1_icon' in request.form:
            tab_icon[0] = request.form['tab1_icon']
        if 'tab2_icon' in request.files:
            tab_icon[1] = request.files['tab2_icon']
        elif 'tab2_icon' in request.form:
            tab_icon[1] = request.form['tab2_icon']
        if 'tab3_icon' in request.files:
            tab_icon[2] = request.files['tab3_icon']
        elif 'tab3_icon' in request.form:
            tab_icon[2] = request.form['tab3_icon']
        if 'tab4_icon' in request.files:
            tab_icon[3] = request.files['tab4_icon']
        elif 'tab4_icon' in request.form:
            tab_icon[3] = request.form['tab4_icon']
        if 'fb1_icon' in request.files:
            fb_icon[0] = request.files['fb1_icon']
        elif 'fb1_icon' in request.form:
            fb_icon[0] = request.form['fb1_icon']
        if 'fb2_icon' in request.files:
            fb_icon[1] = request.files['fb2_icon']
        elif 'fb2_icon' in request.form:
            fb_icon[1] = request.form['fb2_icon']
        if 'fb3_icon' in request.files:
            fb_icon[2] = request.files['fb3_icon']
        elif 'fb3_icon' in request.form:
            fb_icon[2] = request.form['fb3_icon']
        if 'fb4_icon' in request.files:
            fb_icon[3] = request.files['fb4_icon']
        elif 'fb4_icon' in request.form:
            fb_icon[3] = request.form['fb4_icon']
        if 'fb5_icon' in request.files:
            fb_icon[4] = request.files['fb5_icon']
        elif 'fb5_icon' in request.form:
            fb_icon[4] = request.form['fb5_icon']
        vprint("fb_icon: {}".format(fb_icon))
        access_model = int(request.form['access_model'])
        if 'tab3_mode' in request.form:
            tab3_mode = request.form['tab3_mode']
        if 'tab_amount' in request.form:
            tab_amount = int(request.form['tab_amount'])
        if 'font' in request.form:
            font = int(request.form['font'])
        if 'background' in request.files:
            background = request.files['background']
        elif 'background' in request.form:
            background = request.form['background']
        if 'version_code' in request.form:
            version_code = request.form['version_code']
        if 'version_name' in request.form:
            version_name = request.form['version_name']
        else:
            version_name = "1.0.{}".format(version_code)

        path_dest, c_code_path = create_folder(package_id)
        vprint("path_dest: " + path_dest)
        vprint("c_code_path: " + c_code_path)
        if acc:
            change_acc(c_code_path, acc)
        if url:
            change_url(c_code_path, url)
        change_name(path_dest, app_name)
        change_certificate(path_dest, key, keystore, app.keytool)
        change_package(path_dest, package_id)
        change_version(path_dest, version_code,version_name)
        change_font(path_dest, font, package_id)
        if logo:
            change_logo(path_dest, logo, logo_float)
        if background:
            change_background(path_dest, background)
        change_fb(path_dest, fb_icon)
        change_access(path_dest, access_model, package_id)
        change_tab(path_dest, tabs, tab_icon, package_id, tab3_mode, tab_amount)
        os.chdir(path_dest)
        return_code = run_build(path_dest)
        if (return_code == 0):
            return deliver_apk(path_dest, package_id, key, key_exists)
        return "h"
    else:
        if 'e' in request.args:
            return request.args['e']
        return "Hello World!"


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8092, debug=app.verbose, ssl_context=app.ssl)
