import time

import flask
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/QmeraLite"

app.temp_folder = "/apps/3ps/build_apk/BuildApk"
# app.temp_folder = "/Users/easysoft/BuildApk"
app.apk_folder = "/var/www/html/qmera/dashboardv2/uploads"
# app.apk_folder = "/Users/easysoft/"
app.verbose = True
app.ssl =('/etc/ssl/STAR_qmera_io/qmera_io.crt', '/etc/ssl/STAR_qmera_io/qmera.key')
# 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")
    with open(manifest, "r") as f:
        file_source = f.read()
    replaced = file_source.replace("QmeraLite", name)
    with open(manifest, "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)
    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)
    javas = [os.path.join(dp, f) for dp, dn, filenames in os.walk(code_path) for f in filenames]
    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)

def change_logo(path_dest, logo):
    img_path = "app/src/main/res/drawable/ic_launcher.png"
    img_path = os.path.join(path_dest, img_path)
    if isinstance(logo,str):
        logo = requests.get('https://qmera.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((150, 150))
        logo.save(img_path, "PNG")
    else:
        logo = Image.open(logo)
        logo = logo.resize((150,150))
    logo.save(img_path,"PNG")

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:
        with open(keyfile_path, "wb") as f:
            f.write(keyfile)
    else:
        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["password"], "-keypass", key["password"]]
        subprocess.run(cmd)
    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["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'])
    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')
    keystore_name = '{}.keystore'.format(key["alias"])
    keystore_dir = os.path.join(path_dest,keystore_name)
    apk_name = "{}{}.apk".format(package_id,time.time())
    zip_name = "{}{}.zip".format(package_id,time.time())
    new_apk_dir = os.path.join(app.apk_folder,apk_name)
    new_dir = os.path.join(app.apk_folder,zip_name)
    vprint(apk_dir)
    try:
        shutil.move(apk_dir,new_apk_dir)
        with ZipFile(new_dir, 'w') as zip_file:
            zip_file.write(new_apk_dir,os.path.basename(apk_name))
            if not key_exists:
                zip_file.write(keystore_dir,os.path.basename(keystore_dir))
        os.remove(new_apk_dir)
        return {"name": zip_name}
    except Exception as e:
        return str(e)

@app.route('/', methods=["GET","POST"])
def build_apk():
    vprint('==============================================================')
    if request.method == 'POST':
        logo = None
        app_name = "QmeraLite"
        package_id = "com.app.qmera"
        acc = None
        url = None
        keystore = None
        key_exists = False
        key = {"alias": "qmeralite", "password": "allyourbase", "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 '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:
            key["alias"] = request.form['alias']
        if 'password' in request.form:
            if request.form['password']:
                key["password"] = request.form['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']

        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)
        if logo:
            change_logo(path_dest,logo)
        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=8090, debug=app.verbose, ssl_context=app.ssl)
