#!/usr/bin/env python3.8
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

## Roll a new compiler (really, any CIPD package) into Fuchsia

## Usage: See `fx roll-compiler --help`

import argparse
import json
import os
import subprocess
import sys
import tempfile

FUCHSIA_DIR = os.path.normpath(
    os.path.join(__file__, os.pardir, os.pardir, os.pardir, os.pardir)
)
JIRI_BIN = os.path.join(FUCHSIA_DIR, ".jiri_root", "bin")
CIPD = os.path.join(JIRI_BIN, "cipd")
JIRI = os.path.join(JIRI_BIN, "jiri")


def CallCipd(args):
    with tempfile.NamedTemporaryFile(mode="r", suffix=".json") as f:
        cmd = [CIPD] + args + ["-json-output", f.name]
        with open(os.devnull, "w") as devnull:
            subprocess.check_call(cmd, stdout=devnull)
        return json.load(f)["result"]


def ResolvePackage(package, version):
    return CallCipd(["describe", package, "-version", version])


def main():
    parser = argparse.ArgumentParser(
        "fx roll-compiler",
        description="Roll a new compiler into Fuchsia",
        epilog="""
With multiple --package switches, all packages must resolve successfully
before commands are run for any package.
""",
    )
    parser.add_argument(
        "version", nargs="?", default="latest", help="CIPD version to promote"
    )
    parser.add_argument("--package", "-p", action="append", help="CIPD package name")
    parser.add_argument(
        "--manifest",
        default=os.path.join(FUCHSIA_DIR, "integration", "fuchsia", "prebuilts"),
        help="Jiri manifest file to edit",
    )
    parser.add_argument("--tag", default="git_revision", help="CIPD tag to publish")
    parser.add_argument(
        "--platforms",
        action="append",
        metavar="PLATFORM",
        help="CIPD platforms with matching packages",
    )
    parser.add_argument(
        "--dry-run",
        action="store_const",
        default=False,
        const=True,
        help="Only print final command but do not run it",
    )
    args = parser.parse_args()

    if not args.platforms:
        args.platforms = ["linux-arm64", "linux-amd64", "mac-amd64"]

    if not args.package:
        args.package = ["clang"]

    packages = [
        package if "/" in package else "fuchsia/third_party/" + package
        for package in args.package
    ]

    def PackageTag(package):
        [tag] = [
            tag["tag"]
            for tag in package["tags"]
            if tag["tag"].startswith(args.tag + ":")
        ]
        return tag

    def ReifyPackage(package):
        packages = [
            ResolvePackage("%s/%s" % (package, platform), args.version)
            for platform in args.platforms
        ]

        package_tags = {
            package["pin"]["package"]: PackageTag(package) for package in packages
        }
        tag_set = set(t for t in package_tags.values())
        if len(tag_set) != 1:
            sys.stderr.write(
                f"Not all packages have matching {args.tag} tags at version {args.version}:\n")
            json.dump(package_tags, sys.stderr, sort_keys=True, indent=4)
            sys.stderr.write("\n")
            sys.exit(1)
        [tag] = tag_set

        print(f"Resolved {package} ({args.version}) to {tag}")
        return package, tag

    def DryRun(args):
        print(args)

    run = DryRun if args.dry_run else subprocess.check_call

    for package, tag in map(ReifyPackage, packages):
        run(
            [
                JIRI,
                "edit",
                "-package",
                "%s/${platform}=%s" % (package, tag),
                args.manifest,
            ]
        )

    run([os.path.join(FUCHSIA_DIR, "integration", "update-lockfiles.sh")])

    return 0


if __name__ == "__main__":
    sys.exit(main())
