#!/usr/bin/env python3
# Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import argparse
import utils
from html.parser import HTMLParser
import urllib.request
import os
import subprocess
import sys
import xml.etree.ElementTree


JETBRAINS_KOTLIN_STABLE_URL = "https://github.com/JetBrains/kotlin/releases/download"
JETBRAINS_KOTLIN_MAVEN_URL = "https://maven.pkg.jetbrains.space/kotlin/p/" \
                             "kotlin/bootstrap/org/jetbrains/kotlin/"
KOTLIN_RELEASE_URL = JETBRAINS_KOTLIN_MAVEN_URL + "kotlin-compiler/"
KOTLINC_LIB = os.path.join(utils.THIRD_PARTY, "kotlin",
                   "kotlin-compiler-dev", "kotlinc", "lib")

def ParseOptions(args):
    parser = argparse.ArgumentParser(description='Update third_party Kotlin')
    parser.add_argument(
        '--version',
        required=True,
        help="The Kotlin version, use 'dev' for the latest dev compiler")
    return parser.parse_args()

def download_stable(version):
    with utils.TempDir() as temp:
        unzip_dir = os.path.join(
            utils.THIRD_PARTY,
            'kotlin',
            'kotlin-compiler-{version}'.format(version=version))
        if os.path.exists(unzip_dir):
            print('Destination dir {dir} exists. Please remove and retry.'.format(dir=unzip_dir))
            sys.exit(-1)
        url = (
            '{download_url_base}/v{version}/kotlin-compiler-{version}.zip'
                .format(download_url_base=JETBRAINS_KOTLIN_STABLE_URL, version=version))
        kotlin_compiler_download_zip = os.path.join(temp, 'kotlin-compiler.zip')
        download_and_save(url, kotlin_compiler_download_zip)
        cmd = ['unzip', '-q', kotlin_compiler_download_zip, '-d', unzip_dir]
        subprocess.check_call(cmd)
        with open(os.path.join(unzip_dir, 'README.google'), 'w') as readme:
            readme.write('Name: Kotlin\n')
            readme.write('URL: {url}\n'.format(url=url))
            readme.write('Version: {version}\n'.format(version=version))
            readme.write('Revision: NA\n')
            readme.write('License: Apache License Version 2.0\n')
    print('If you want to upload this run:')
    print('  (cd {dir}; upload_to_google_storage.py -a --bucket r8-deps {file})'
        .format(dir=os.path.dirname(unzip_dir), file=os.path.basename(unzip_dir)))





def download_newest():
    response = url_request.urlopen(KOTLIN_RELEASE_URL)
    if response.getcode() != 200:
        raise Exception('Url: %s \n returned %s' %
                        (KOTLIN_RELEASE_URL, response.getcode()))
    content = str(response.read())
    release_candidates = []

    class HTMLContentParser(HTMLParser):

        def handle_data(self, data):
            if ('-dev-' in data):
                release_candidates.append(data)

    parser = HTMLContentParser()
    parser.feed(content)

    top_most_version = (0, 0, 0, 0)
    top_most_version_and_build = None

    for version in release_candidates:
        # The compiler version is on the form <major>.<minor>.<revision>-dev-<build>/
        version = version.replace('/', '')
        version_build_args = version.split('-')
        version_components = version_build_args[0].split('.')
        version_components.append(version_build_args[2])
        current_version = tuple(map(int, version_components))
        if (current_version > top_most_version):
            top_most_version = current_version
            top_most_version_and_build = version

    if (top_most_version_and_build is None):
        raise Exception('Url: %s \n returned %s' %
                        (KOTLIN_RELEASE_URL, response.getcode()))

    # Download checked in kotlin dev compiler before owerlaying with the new.
    # TODO(sgjesse): This should just ensure an empty directory instead of
    # relying on overlaying and reusing some jars.
    utils.DownloadFromGoogleCloudStorage(
        os.path.join(utils.THIRD_PARTY, "kotlin",
                     "kotlin-compiler-dev.tar.gz.sha1"))

    # Check POM for expected dependencies.
    check_pom(top_most_version_and_build)

    # We can now download all files related to the kotlin compiler version.
    print("Downloading version: " + top_most_version_and_build)

    download_and_save(
        JETBRAINS_KOTLIN_MAVEN_URL +
        "kotlin-compiler/{0}/kotlin-compiler-{0}.jar".format(
            top_most_version_and_build), KOTLINC_LIB, "kotlin-compiler.jar")
    download_and_save(
        JETBRAINS_KOTLIN_MAVEN_URL +
        "kotlin-stdlib/{0}/kotlin-stdlib-{0}.jar".format(
            top_most_version_and_build), KOTLINC_LIB, "kotlin-stdlib.jar")
    download_and_save(
        JETBRAINS_KOTLIN_MAVEN_URL +
        "kotlin-stdlib-jdk8/{0}/kotlin-stdlib-jdk8-{0}.jar".format(
            top_most_version_and_build), KOTLINC_LIB, "kotlin-stdlib-jdk8.jar")
    # POM file has dependency on version 1.6.10 - download latest anyway.
    download_and_save(
        JETBRAINS_KOTLIN_MAVEN_URL +
        "kotlin-reflect/{0}/kotlin-reflect-{0}.jar".format(
            top_most_version_and_build), KOTLINC_LIB, "kotlin-reflect.jar")
    download_and_save(
        JETBRAINS_KOTLIN_MAVEN_URL +
        "kotlin-script-runtime/{0}/kotlin-script-runtime-{0}.jar".format(
            top_most_version_and_build), KOTLINC_LIB,
        "kotlin-script-runtime.jar")
    download_and_save(
        "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.8.0/kotlinx-coroutines-core-jvm-1.8.0.jar", KOTLINC_LIB, "kotlinx-coroutines-core-jvm.jar")
    download_and_save(
        "https://repo1.maven.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar", KOTLINC_LIB, "trove4j.jar")


def check_pom(top_most_version_and_build):
    # Download POM, and check the expected dependencies.
    download_and_save(
        JETBRAINS_KOTLIN_MAVEN_URL +
        "kotlin-compiler/{0}/kotlin-compiler-{0}.pom".format(
            top_most_version_and_build), KOTLINC_LIB, "kotlin-compiler.pom")
    pom_file = os.path.join(KOTLINC_LIB, "kotlin-compiler.pom")
    ns = "http://maven.apache.org/POM/4.0.0"
    xml.etree.ElementTree.register_namespace('', ns)
    tree = xml.etree.ElementTree.ElementTree()
    tree.parse(pom_file)
    #return tree.getroot().find("{%s}dependencies" % ns).text
    for dependency in tree.getroot().find("{%s}dependencies" % ns):
        groupId = dependency.find("{%s}groupId" % ns).text
        artifactId = dependency.find("{%s}artifactId" % ns).text
        version = dependency.find("{%s}version" % ns).text
        coordinates = (
            '{groupId}:{artifactId}:{version}'
                .format(groupId=groupId, artifactId=artifactId, version=version))
        print('Dependecy: ' + coordinates)
        expected_dependencies = set()
        for artifactId in ("kotlin-stdlib", "kotlin-stdlib-jdk8", "kotlin-script-runtime"):
            expected_dependencies.add(
                'org.jetbrains.kotlin:{artifactId}:{version}'
                    .format(artifactId=artifactId, version=top_most_version_and_build))
        expected_dependencies.add('org.jetbrains.kotlin:kotlin-reflect:1.6.10')
        expected_dependencies.add('org.jetbrains.intellij.deps:trove4j:1.0.20200330')
        expected_dependencies.add('org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0')
        if not coordinates in expected_dependencies:
            raise Exception('Unexpected dependency: ' + coordinates)


def download_and_save(url, path, name):
    download_and_save(url, dest)


def download_and_save(url, dest):
    print('Downloading: ' + url + ' to: ' + dest)
    urllib.request.urlretrieve(url, dest)


def main(args):
    options = ParseOptions(args)
    print(options.version)
    if options.version == 'dev':
        download_newest()
    else:
        download_stable(options.version)


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
