#!/usr/bin/env python2.7
# 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 into goma or 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 goma or into Fuchsia',
        epilog='''
With multiple --package switches, all packages must resolve successfully
before commands are run for any package.
''')
    parser.add_argument(
        'to', choices=('goma', 'fuchsia'), help='Either "goma" or "fuchsia"')
    parser.add_argument('version', nargs='?', 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('--ref', default='goma', help='CIPD ref to publish')
    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 args.version is None:
        # When promoting to Goma (step 1), use the latest package by default.
        # When promoting to Fuchsia (step 2), use the --ref value, i.e.
        # the version that was presumably promoted in step 1.
        args.version = 'latest' if args.to == 'goma' else args.ref

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

    if not args.package:
        args.package = ['fuchsia/third_party/clang']

    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(package_tags.itervalues())
        if len(tag_set) != 1:
            sys.stderr.write(
                'Not all packages have matching %s tags at version %s:\n' %
                (args.tag, args.version))
            json.dump(package_tags, sys.stderr, sort_keys=True, indent=4)
            sys.stderr.write('\n')
            sys.exit(1)
        [tag] = tag_set

        print 'Resolved %s (%s) to %s' % (package, args.version, 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, args.package):
        if args.to == 'goma':
            run(
                [
                    CIPD,
                    'set-ref',
                    package + '/',
                    '-ref',
                    args.ref,
                    '-version',
                    tag,
                ])
        else:
            run(
                [
                    JIRI,
                    'edit',
                    '-package',
                    '%s/${platform}=%s' % (package, tag),
                    args.manifest,
                ])

    if args.to == 'fuchsia':
        run([os.path.join(FUCHSIA_DIR, 'integration', 'update-lockfiles.sh')])

    return 0


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