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

from common import (FUCHSIA_ROOT, run_command, is_tree_clean, fx_format)

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 fxbug.dev/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(fxbug.dev/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.
    fx_format(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.
    if not is_tree_clean():
        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())
