import subprocess
from distutils.version import StrictVersion
import paramiko
from scp import SCPClient
import os
from glob import glob
import tempfile


# --------------------------------------------- Config ----------------------------------------------------------

NODE_PATH = "/home/martin/node-v14.17.0-linux-x64/bin"
JDK8_PATH = "/usr/lib/jvm/java-8-openjdk-amd64/bin/"

PUBLIC_URL = "https://swimtracker.bauer.tech"
DEPLOY_HOST = "server"
DEPLOY_PATH = "/volumes/swimtracker"

APP_UPDATE_FOLDER = "app-update"
APP_FOLDER = "app"

# ---------------------------------------------------------------------------------------------------------------


def create_env_with_node_path():
    env = os.environ.copy()
    env["PATH"] = NODE_PATH + ":" + JDK8_PATH + ":" + env['PATH']
    return env


def create_ssh_client(server, port, user):
    client = paramiko.SSHClient()
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(server, port, user)
    return client


def version_number_from_git(tag_prefix='release/', sha_length=10, version_format="{version}.dev{commits}+{sha}"):
    def get_released_versions():
        tags = sorted(subprocess.getoutput('git tag').split('\n'))
        versions = [t[len(tag_prefix):]
                    for t in tags if t.startswith(tag_prefix)]
        return versions

    def tag_from_version(v):
        return tag_prefix + v

    def increment_version(v):
        parsed_version = [int(i) for i in v.split('.')]
        parsed_version[-1] += 1
        return '.'.join(str(i) for i in parsed_version)

    version_strings = get_released_versions()
    version_strings.sort(key=StrictVersion)
    latest_release = version_strings[-1]
    commits_since_tag = subprocess.getoutput(
        'git rev-list {}..HEAD --count'.format(tag_from_version(latest_release)))
    sha = subprocess.getoutput('git rev-parse HEAD')[:sha_length]
    is_dirty = len(subprocess.getoutput(
        "git status --untracked-files=no -s")) > 0

    if int(commits_since_tag) == 0:
        version_string = latest_release
    else:
        next_version = increment_version(latest_release)
        version_string = version_format.format(
            version=next_version, commits=commits_since_tag, sha=sha)

    if is_dirty:
        version_string += ".dirty"
    return version_string


#
env_with_node_path = create_env_with_node_path()
ssh = create_ssh_client(DEPLOY_HOST, 22, "root")
scp = SCPClient(ssh.get_transport())
android_idx_url = f"{PUBLIC_URL}/{APP_UPDATE_FOLDER}/android-index.json"
version_name = version_number_from_git()


def deploy_apk_update_files():
    cmd = [f"expo", "export", "--public-url", f"{PUBLIC_URL}/{APP_UPDATE_FOLDER}"]
    subprocess.check_call(cmd, env=env_with_node_path)
    scp.put(glob('dist/*'), recursive=True,
            remote_path=os.path.join(DEPLOY_PATH, APP_UPDATE_FOLDER))


def deploy_apk():
    with tempfile.TemporaryDirectory() as tmpdirname:
        apk_file = os.path.join(tmpdirname, "app.apk")
        cmd = ["turtle", "build:android", "--type", "apk", "--public-url", android_idx_url,
               "-o", apk_file]
        subprocess.check_call(cmd, env=env_with_node_path)
        target_file = os.path.join(DEPLOY_PATH, APP_FOLDER, f"swimtracker-{version_name}.apk")
        scp.put(apk_file, target_file)


def deploy_web():
    cmd = [f"expo", "build:web"]
    subprocess.check_call(cmd, env=env_with_node_path)
    scp.put('web-build', recursive=True,
            remote_path=os.path.join(DEPLOY_PATH, APP_FOLDER))



if __name__ == "__main__":
    print("----------- Building Web    ------------------")
    deploy_web()  
    print("Deploying version {}", version_name)
    print("----------- Exporting deploy files -----------")
    deploy_apk_update_files()
    print("----------- Building APK    ------------------")
    deploy_apk()
