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

# 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/"

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

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()
