#!/usr/bin/env python3
# Simpler reimplementation of Android's sdkmanager
# Extra features of this implementation are pinning and mirroring

import argparse
import hashlib
import os
import subprocess
import tempfile
import urllib.request
import xml.etree.ElementTree as ET

# These URLs are the Google repositories containing the list of available
# packages and their versions. The list has been generated by listing the URLs
# fetched while executing `tools/bin/sdkmanager --list`
BASE_REPOSITORY = "https://dl.google.com/android/repository/"
REPOSITORIES = [
    "sys-img/android/sys-img2-1.xml",
    "sys-img/android-wear/sys-img2-1.xml",
    "sys-img/android-wear-cn/sys-img2-1.xml",
    "sys-img/android-tv/sys-img2-1.xml",
    "sys-img/google_apis/sys-img2-1.xml",
    "sys-img/google_apis_playstore/sys-img2-1.xml",
    "addon2-1.xml",
    "glass/addon2-1.xml",
    "extras/intel/addon2-1.xml",
    "repository2-1.xml",
]

# Available hosts: linux, macosx and windows
HOST_OS = "linux"

# Mirroring options
MIRROR_BUCKET = "rust-lang-ci-mirrors"
MIRROR_BUCKET_REGION = "us-west-1"
MIRROR_BASE_DIR = "rustc/android/"


class Package:
    def __init__(self, path, url, sha1, deps=None):
        if deps is None:
            deps = []
        self.path = path.strip()
        self.url = url.strip()
        self.sha1 = sha1.strip()
        self.deps = deps

    def download(self, base_url):
        _, file = tempfile.mkstemp()
        url = base_url + self.url
        subprocess.run(["curl", "-o", file, url], check=True)
        # Ensure there are no hash mismatches
        with open(file, "rb") as f:
            sha1 = hashlib.sha1(f.read()).hexdigest()
            if sha1 != self.sha1:
                raise RuntimeError(
                    "hash mismatch for package "
                    + self.path
                    + ": "
                    + sha1
                    + " vs "
                    + self.sha1
                    + " (known good)"
                )
        return file

    def __repr__(self):
        return "<Package " + self.path + " at " + self.url + " (sha1=" + self.sha1 + ")"


def fetch_url(url):
    page = urllib.request.urlopen(url)
    return page.read()


def fetch_repository(base, repo_url):
    packages = {}
    root = ET.fromstring(fetch_url(base + repo_url))
    for package in root:
        if package.tag != "remotePackage":
            continue
        path = package.attrib["path"]

        for archive in package.find("archives"):
            host_os = archive.find("host-os")
            if host_os is not None and host_os.text != HOST_OS:
                continue
            complete = archive.find("complete")
            url = os.path.join(os.path.dirname(repo_url), complete.find("url").text)
            sha1 = complete.find("checksum").text

            deps = []
            dependencies = package.find("dependencies")
            if dependencies is not None:
                for dep in dependencies:
                    deps.append(dep.attrib["path"])

            packages[path] = Package(path, url, sha1, deps)
            break

    return packages


def fetch_repositories():
    packages = {}
    for repo in REPOSITORIES:
        packages.update(fetch_repository(BASE_REPOSITORY, repo))
    return packages


class Lockfile:
    def __init__(self, path):
        self.path = path
        self.packages = {}
        if os.path.exists(path):
            with open(path) as f:
                for line in f:
                    path, url, sha1 = line.split(" ")
                    self.packages[path] = Package(path, url, sha1)

    def add(self, packages, name, *, update=True):
        if name not in packages:
            raise NameError("package not found: " + name)
        if not update and name in self.packages:
            return
        self.packages[name] = packages[name]
        for dep in packages[name].deps:
            self.add(packages, dep, update=False)

    def save(self):
        packages = list(sorted(self.packages.values(), key=lambda p: p.path))
        with open(self.path, "w") as f:
            for package in packages:
                f.write(package.path + " " + package.url + " " + package.sha1 + "\n")


def cli_add_to_lockfile(args):
    lockfile = Lockfile(args.lockfile)
    packages = fetch_repositories()
    for package in args.packages:
        lockfile.add(packages, package)
    lockfile.save()


def cli_update_mirror(args):
    lockfile = Lockfile(args.lockfile)
    for package in lockfile.packages.values():
        path = package.download(BASE_REPOSITORY)
        subprocess.run(
            [
                "aws",
                "s3",
                "mv",
                path,
                "s3://" + MIRROR_BUCKET + "/" + MIRROR_BASE_DIR + package.url,
                "--profile=" + args.awscli_profile,
            ],
            check=True,
        )


def cli_install(args):
    lockfile = Lockfile(args.lockfile)
    for package in lockfile.packages.values():
        # Download the file from the mirror into a temp file
        url = (
            "https://"
            + MIRROR_BUCKET
            + ".s3-"
            + MIRROR_BUCKET_REGION
            + ".amazonaws.com/"
            + MIRROR_BASE_DIR
        )
        downloaded = package.download(url)
        # Extract the file in a temporary directory
        extract_dir = tempfile.mkdtemp()
        subprocess.run(
            [
                "unzip",
                "-q",
                downloaded,
                "-d",
                extract_dir,
            ],
            check=True,
        )
        # Figure out the prefix used in the zip
        subdirs = [d for d in os.listdir(extract_dir) if not d.startswith(".")]
        if len(subdirs) != 1:
            raise RuntimeError("extracted directory contains more than one dir")
        # Move the extracted files in the proper directory
        dest = os.path.join(args.dest, package.path.replace(";", "/"))
        os.makedirs("/".join(dest.split("/")[:-1]), exist_ok=True)
        os.rename(os.path.join(extract_dir, subdirs[0]), dest)
        os.unlink(downloaded)


def cli():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()

    add_to_lockfile = subparsers.add_parser("add-to-lockfile")
    add_to_lockfile.add_argument("lockfile")
    add_to_lockfile.add_argument("packages", nargs="+")
    add_to_lockfile.set_defaults(func=cli_add_to_lockfile)

    update_mirror = subparsers.add_parser("update-mirror")
    update_mirror.add_argument("lockfile")
    update_mirror.add_argument("--awscli-profile", default="default")
    update_mirror.set_defaults(func=cli_update_mirror)

    install = subparsers.add_parser("install")
    install.add_argument("lockfile")
    install.add_argument("dest")
    install.set_defaults(func=cli_install)

    args = parser.parse_args()
    if not hasattr(args, "func"):
        print("error: a subcommand is required (see --help)")
        exit(1)
    args.func(args)


if __name__ == "__main__":
    cli()
