#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import argparse
import json
import os
from pathlib import Path
import re
import subprocess
import shutil
import sys
import tempfile
import time
from urllib.request import urlopen, urlretrieve

ASSET_PREFIX = "lowrisc-toolchain-gcc-rv32imc-"
ASSET_SUFFIX = ".tar.xz"
BUILDINFO_FILENAME = "buildinfo"
RELEASES_URL_BASE = 'https://api.github.com/repos/lowRISC/lowrisc-toolchains/releases'
TARGET_DIR = '/tools/riscv'
TOOLCHAIN_VERSION = 'latest'
VERSION_RE=r"(lowRISC toolchain version|Version):\s*\n(?P<version>\d+(-\d+)?)"


def prompt_yes_no(msg):
    while True:
        print(msg, end=" ")
        response = input().lower()
        if response in ('yes', 'y'):
            return True
        elif response in ('no', 'n'):
            return False
        else:
            print('Invalid response. Valid options are "yes" or "no"')


def get_release_info(toolchain_version):
    if toolchain_version == 'latest':
        releases_url = '%s/%s' % (RELEASES_URL_BASE, toolchain_version)
    else:
        releases_url = '%s/tags/%s' % (RELEASES_URL_BASE, toolchain_version)
    with urlopen(releases_url) as f:
        return json.loads(f.read().decode('utf-8'))


def get_download_url(release_info):
    return [
        a["browser_download_url"] for a in release_info["assets"]
        if (a["name"].startswith(ASSET_PREFIX) and
            a["name"].endswith(ASSET_SUFFIX))
    ][0]


def get_release_tag(release_info):
    return release_info["tag_name"]


def get_release_tag_from_file(buildinfo_file):
    """Extracts version tag from buildinfo file.

    Args:
        buildinfo_file: Path to buildinfo_file.
    Returns:
        Release tag string if available, otherwise None.
    """
    with open(buildinfo_file, 'r') as f:
        match = re.match(VERSION_RE, f.read(), re.M)
    if not match:
        return None
    return match.group("version")


def download(url):
    print("Downloading toolchain from %s" % (url, ))
    tmpfile = tempfile.mktemp()
    urlretrieve(url, tmpfile)
    return tmpfile


def install(archive_file, target_dir):
    os.makedirs(target_dir)

    cmd = [
        'tar', '-x', '-f', archive_file, '--strip-components=1', '-C',
        target_dir
    ]
    subprocess.run(cmd, check=True)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--target-dir',
        '-t',
        required=False,
        default=TARGET_DIR,
        help="Target directory (must not exist) (default: %(default)s)")
    parser.add_argument(
        '--release-version',
        '-r',
        required=False,
        default=TOOLCHAIN_VERSION,
        help="Toolchain version (default: %(default)s)")
    parser.add_argument(
        '--update',
        '-u',
        required=False,
        default=False,
        action='store_true',
        help="Set to update to target version if needed (default: %(default)s)")
    parser.add_argument(
        '--force',
        '-f',
        required=False,
        default=False,
        action='store_true',
        help="Set to skip directory erase prompt when --update is set "
            "(default: %(default)s)")
    args = parser.parse_args()

    target_dir = args.target_dir
    toolchain_version = args.release_version

    if not args.update and os.path.exists(args.target_dir):
        sys.exit('Target directory %s already exists. Delete it first '
             'it you want to re-download the toolchain.' % (target_dir, ))

    release_info = get_release_info(toolchain_version)

    if args.update and os.path.exists(args.target_dir):
        buildinfo_file = str(Path(target_dir) / BUILDINFO_FILENAME)
        if not os.path.exists(buildinfo_file):
            sys.exit('Unable to find buildinfo file at %s. Delete target '
                'directory and try again.' % buildinfo_file)
        current_release_tag = get_release_tag_from_file(buildinfo_file)
        if not current_release_tag and not args.force:
            # If args.force is set then we can skip this error condition. The
            # version check test condition will also fail, and the install
            # will continue.
            sys.exit('Unable to extract current toolchain version from %s. '
                'Delete target directory and try again.' % buildinfo_file)
        if get_release_tag(release_info) == current_release_tag:
            print('Toolchain version %s already installed at %s. Skipping '
                'install.' % (current_release_tag, target_dir))
            return

    download_url = get_download_url(release_info)
    try:
        archive_file = download(download_url)
        if args.update and os.path.exists(args.target_dir):
            # Warn the user before deleting the target directory.
            warning_msg = 'WARNING: Removing directory: %s.' % target_dir
            if not args.force:
                if not prompt_yes_no(warning_msg + ' Continue [yes/no]:'):
                    sys.exit('Aborting update.')
            else:
                print(warning_msg)
            shutil.rmtree(target_dir)
        install(archive_file, target_dir)
    finally:
        os.remove(archive_file)

    print('Toolchain downloaded and installed to %s' % (target_dir, ))


if __name__ == "__main__":
    main()
