#!/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.

import argparse
import fileinput
import json
import operator
import os
import re
import subprocess
import sys


SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
SCRIPTS_DIR = os.path.dirname(SCRIPT_DIR)
FUCHSIA_ROOT = os.path.dirname(SCRIPTS_DIR)
FX = os.path.join(SCRIPTS_DIR, 'fx')

SCRIPT_LABEL = '//' + os.path.relpath(os.path.abspath(__file__),
                                      start=FUCHSIA_ROOT)

BRANCH_PREFIX = 'gn-move-'


class Type(object):
    DRIVER = 'zx_driver'
    EXECUTABLE = 'zx_executable'
    TEST = 'zx_test'
    TEST_DRIVER = 'zx_test_driver'
    @classmethod
    def all(cls): return [cls.DRIVER, cls.EXECUTABLE, cls.TEST, cls.TEST_DRIVER]


BINARY_TYPES = {
    Type.DRIVER: 'driver_module',
    Type.EXECUTABLE: 'executable',
    Type.TEST: 'test',
    Type.TEST_DRIVER: 'driver_module',
}

TARGET_SCORES = {
    Type.DRIVER: 1,
    Type.EXECUTABLE: 1,
    Type.TEST: 1,
    Type.TEST_DRIVER: 1,
    'banjo_library': 100,
    'fidl_library': 100,
    'config': 1000,
    'fuzzer': 1000,
    'zx_library': 1000,
    'zx_host_tool': 1000,
}


def run_command(command):
    return subprocess.check_output(command, cwd=FUCHSIA_ROOT)


def locate_build_files(base):
    result = []
    for root, dirs, files in os.walk(os.path.join(FUCHSIA_ROOT, 'zircon',
                                    'system', base)):
        for file in files:
            if file == 'BUILD.gn':
                result.append(os.path.join(root, file))
    return result


def transform_build_file(build):
    # First pass: identify contents of the build file.
    binaries = []
    has_test_binaries = False
    has_drivers = False
    binary_types = BINARY_TYPES.keys()
    unclear_types = ['library']
    n_lines = 0
    with open(build, 'r') as build_file:
        lines = build_file.readlines()
        n_lines = len(lines)
        for line in lines:
            match = re.match(r'\A([^\(]+)\("([^"]+)"\)', line)
            if match:
                type, name = match.groups()
                if type in binary_types:
                    binaries.append(name)
                    if type == Type.TEST:
                        has_test_binaries = True
                    if type == Type.DRIVER or type == Type.TEST_DRIVER:
                        has_drivers = True
                if type in unclear_types:
                    print('Warning: target ' + name + ' of type ' + type + ' '
                          'needs to be manually converted.')

    # Second pass: rewrite contents to match GN build standards.
    imports_added = False
    for line in fileinput.FileInput(build, inplace=True):
        # Apply required edits.
        # Update target types.
        starting_type = ''
        for type in binary_types:
            new_type_line = line.replace(type, BINARY_TYPES[type])
            if new_type_line != line:
                starting_type = type
                line = new_type_line
                break
        # Remove references to libzircon.
        if '$zx/system/ulib/zircon' in line and not 'zircon-internal' in line:
            line = ''
        # Update references to libraries.
        line = line.replace('$zx/system/ulib', '//zircon/public/lib')
        line = line.replace('$zx/system/dev/lib', '//zircon/public/lib')
        # Update references to Zircon in general.
        line = line.replace('$zx', '//zircon')
        # Update import for fuzzers.
        line = line.replace('//zircon/public/gn/fuzzer.gni', '//build/fuzzing/fuzzer.gni')
        # Update references to firmware.
        line = line.replace('//zircon/public/gn/firmware.gni', '//build/unification/firmware.gni')
        line = line.replace('$firmware_dir/', '')
        # Update deps on libdriver.
        line = line.replace('//zircon/public/lib/driver', '//src/devices/lib/driver')
        # Print the line, if any content is left.
        if line:
            sys.stdout.write(line)

        # Insert required imports at the start of the file.
        if not line.strip() and not imports_added:
            imports_added = True
            sys.stdout.write('##########################################\n')
            sys.stdout.write('# Though under //zircon, this build file #\n')
            sys.stdout.write('# is meant to be used in the Fuchsia GN  #\n')
            sys.stdout.write('# build.                                 #\n')
            sys.stdout.write('# See fxb/36139.                         #\n')
            sys.stdout.write('##########################################\n')
            sys.stdout.write('\n')
            sys.stdout.write('assert(!defined(zx) || zx != "/", "This file can only be used in the Fuchsia GN build.")\n')
            sys.stdout.write('\n')
            if has_drivers:
                sys.stdout.write('import("//build/config/fuchsia/rules.gni")\n')
            if has_test_binaries:
                sys.stdout.write('import("//build/test.gni")\n')
            sys.stdout.write('import("//build/unification/images/migrated_manifest.gni")\n')
            sys.stdout.write('\n')

        # Add extra parameters to tests.
        if starting_type == Type.TEST:
            sys.stdout.write('  # Dependent manifests unfortunately cannot be marked as `testonly`.\n')
            sys.stdout.write('  # TODO(44278): Remove when converting this file to proper GN build idioms.\n')
            sys.stdout.write('  if (is_fuchsia) {\n')
            sys.stdout.write('    testonly = false\n')
            sys.stdout.write('  }\n')

        if starting_type == Type.TEST_DRIVER:
            sys.stdout.write('  test = true\n')

        if starting_type in [Type.DRIVER, Type.TEST_DRIVER]:
            sys.stdout.write('  defines = [ "_ALL_SOURCE" ]\n')
            sys.stdout.write('  configs += [ "//build/config/fuchsia:enable_zircon_asserts" ]\n')
            sys.stdout.write('  configs -= [ "//build/config/fuchsia:no_cpp_standard_library" ]\n')
            sys.stdout.write('  configs += [ "//build/config/fuchsia:static_cpp_standard_library" ]\n')

        if starting_type in Type.all():
            sys.stdout.write('  if (is_fuchsia) {\n')
            sys.stdout.write('    configs += [ "//build/unification/config:zircon-migrated" ]\n')
            sys.stdout.write('  }\n')

        if starting_type in [Type.EXECUTABLE, Type.TEST]:
            sys.stdout.write('  if (is_fuchsia) {\n')
            sys.stdout.write('    fdio_config = [ "//build/config/fuchsia:fdio_config" ]\n')
            sys.stdout.write('    if (configs + fdio_config - fdio_config != configs) {\n')
            sys.stdout.write('      configs -= fdio_config\n')
            sys.stdout.write('    }\n')
            sys.stdout.write('  }\n')

    # Third pass: add manifest targets at the end of the file.
    with open(build, 'a') as build_file:
        for binary in binaries:
            build_file.write('\n')
            build_file.write('migrated_manifest("' + binary + '-manifest") {\n')
            build_file.write('  deps = [\n')
            build_file.write('    ":' + binary + '",\n')
            build_file.write('  ]\n')
            build_file.write('}\n')

    # Format the file.
    run_command([FX, 'format-code', '--files=' + build])

    return 0


def score_file(path):
    total = 0
    with open(os.path.join(FUCHSIA_ROOT, 'zircon', 'system', path, 'BUILD.gn'), 'r') as build_file:
        content = build_file.read()
        for word, score in TARGET_SCORES.iteritems():
            instances = len(re.findall(r'^\s*' + word + '\(', content, re.MULTILINE))
            total += instances * score
    return total



def main():
    parser = argparse.ArgumentParser(
            description='Moves a binary from ZN to GN.')
    commands = parser.add_subparsers()

    convert_parser = commands.add_parser('convert',
                                         help='Migrate from ZN to GN')
    convert_parser.add_argument('binary',
                        help='The binary under //zircon/system to migrate, '
                             'e.g. uapp/audio, utest/fit, dev/bus/pci')
    convert_parser.add_argument('--from-current-branch',
                                help='use the current branch as parent rather than JIRI_HEAD',
                                action="store_true")
    convert_parser.set_defaults(func=run_convert)

    list_parser = commands.add_parser('list',
                                      help='List available binaries')
    list_parser.add_argument('--build-dir',
                             help='path to the ZN build dir',
                             default=os.path.join(FUCHSIA_ROOT, 'out', 'default.zircon'))
    list_parser.add_argument('--sorted',
                             help='whether to sort the list by decreasing difficulty',
                             action='store_true')
    list_parser.set_defaults(func=run_list)

    args = parser.parse_args()
    args.func(args)


def run_convert(args):
    # Check that the fuchsia.git tree is clean.
    diff = run_command(['git', 'status', '--porcelain'])
    if diff:
        print('Please make sure your tree is clean before running this script')
        print(diff)
        return 1

    # Identify the affected build files.
    build_files = locate_build_files(args.binary)
    if not build_files:
        print('Error: could not find any files for ' + args.binary)
        return 1

    # Confirm with the user that these are the files they want to convert.
    print('The following build file(s) will be converted:')
    for file in build_files:
        print(' - ' + os.path.relpath(file, FUCHSIA_ROOT))
    go_ahead = raw_input('Proceed? (Y/n) ').lower().strip()
    if go_ahead != 'y' and go_ahead != '':
        print('User disagrees, exiting')
        return 0

    # Determine what branch to start from.
    branch_args = ['JIRI_HEAD']
    if args.from_current_branch:
        head = run_command(['git', 'symbolic-ref', '--short', '-q', 'HEAD']).strip()
        if not head.startswith(BRANCH_PREFIX):
            print('Error: should start from a migration branch (i.e. named "%sfoo").' %
                  BRANCH_PREFIX)
            return 1
        branch_args = ['-t', head]

    # Convert the build files.
    for file in build_files:
        transform_build_file(file)

    # Create a commit.
    id = args.binary.replace('/', '_')
    run_command(['git', 'checkout', '-b', BRANCH_PREFIX + id] + branch_args)

    run_command(['git', 'add', '.'])
    message = [
        '[unification] Move //zircon/system/' + args.binary + ' to the GN build',
        '',
        'Generated with: ' + SCRIPT_LABEL,
        '',
        'scripts/unification/verify_element_move.py --reference local/initial.json:',
        'TODO PASTE VERIFICATION RESULT HERE',
        '',
        'Bug: 36139'
    ]
    commit_command = ['git', 'commit', '-a']
    for line in message:
        commit_command += ['-m', line]
    run_command(commit_command)

    print('Base change is ready. Please attempt to build a full system to '
          'identify further required changes.')

    return 0


def run_list(args):
    scores = {}
    for arch in ['arm64', 'x64']:
        manifest_path = os.path.join(args.build_dir,
                                     'legacy_unification-%s.json' % arch)
        with open(manifest_path, 'r') as manifest_file:
            data = json.load(manifest_file)
        for item in data:
            if item['name'].startswith('lib.'):
                # Libraries will be migrated through a different process.
                continue
            label = item['label']
            # Labels are always full, i.e. "//foo/bar:blah(//toolchain)".
            label = label[0:label.index('(')]
            label = label[0:label.index(':')]
            if not label.startswith('//system'):
                continue
            label = label[len('//system/'):]
            score = score_file(label) if args.sorted else 0
            scores.setdefault(score, set()).add(label)
    for score, labels in sorted(scores.items(),
                                key=operator.itemgetter(0),
                                reverse=True):
        for label in sorted(labels):
            print(label)
        if args.sorted:
            print('-------------------------------------')


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