#!/usr/bin/env python
# Copyright 2017 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 errno
import os
import re
import shutil
import subprocess
import sys


SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
FUCHSIA_ROOT = os.path.dirname(  # $root
    os.path.dirname(             # build
        SCRIPT_DIR))                 # zircon
ZIRCON_ROOT = os.path.join(FUCHSIA_ROOT, 'zircon')

sys.path += [os.path.join(FUCHSIA_ROOT, 'third_party', 'mako')]
from mako.lookup import TemplateLookup
from mako.template import Template


# Packages included in the sysroot.
SYSROOT_PACKAGES = ['c', 'zircon']

# Prefixes of Zircon headers that should not appear in SDKs.
NON_SDK_SYSROOT_HEADER_PREFIXES = [
    'zircon/device',
    'zircon/syscalls/definitions.rs',
]
# TODO(FIDL-273): remove this allowlist.
MANDATORY_SDK_HEADERS = [
    'zircon/device/ioctl.h',         # Needed by zircon/device/ramdisk.h
    'zircon/device/ioctl-wrapper.h', # Needed by zircon/device/ramdisk.h
    # TODO(ZX-2503): remove this entry.
    'zircon/device/ramdisk.h',       # Needed by fs-management/ramdisk.h
    'zircon/device/sysinfo.h',       # Needed by some external clients
]

# List of libraries with header files being transitioned from
# 'include/foo/foo.h' to 'include/lib/foo/foo.h'. During the transition, both
# the library's 'include/' and 'include/lib' directories are added to the
# include path so both old and new style include work.
# TODO(ZX-1871): Once everything in Zircon is migrated, remove this mechanism.
LIBRARIES_BEING_MOVED = ['zx']

# Prebuilt libraries for which headers shouldn't be included in an SDK.
# While this kind of mechanism exists in the GN build, there's no equivalent in
# the make build and we have to manually curate these libraries.
LIBRARIES_WITHOUT_SDK_HEADERS = ['trace-engine']

# Packages which should never appear in SDKs.
# Dependencies on these packages will not be reflected in generated rules. The
# lack of distinction between public and private deps in the make build system
# is the reason why this list is needed.
NON_SDK_DEPS = ['zircon-internal']

def make_dir(path, is_dir=False):
    '''Creates the directory at `path`.'''
    target = path if is_dir else os.path.dirname(path)
    try:
        os.makedirs(target)
    except OSError as exception:
        if exception.errno == errno.EEXIST and os.path.isdir(target):
            pass
        else:
            raise


def try_remove(list, element):
    '''Attempts to remove an element from a list, returning `true` if
       successful.'''
    try:
        list.remove(element)
        return True
    except ValueError:
        return False


def parse_package(lines):
    '''Parses the content of a package file.'''
    result = {}
    section_exp = re.compile('^\[([^\]]+)\]$')
    attr_exp = re.compile('^([^=]+)=(.*)$')
    current_section = None

    def finalize_section():
        if not current_section:
            return
        if current_list and current_map:
            raise Exception('Found both map-style and list-style section')
        result[current_section] = (current_map if current_map
                                   else current_list)
    for line in lines:
        section_match = section_exp.match(line)
        if section_match:
            finalize_section()
            current_section = section_match.group(1)
            current_list = []
            current_map = {}
            continue
        attr_match = attr_exp.match(line)
        if attr_match:
            name = attr_match.group(1)
            value = attr_match.group(2)
            current_map[name] = value
        else:
            current_list.append(line.strip())
    finalize_section()
    return result


def extract_file(name, path, context, is_tool=False):
    '''Extracts file path and base folder path from a map entry.'''
    # name: foo/bar.h
    # path: <SOURCE|BUILD>/somewhere/under/zircon/foo/bar.h
    (full_path, changes) = re.subn('^SOURCE', context.source_base, path)
    build_base = context.tool_build_base if is_tool else context.user_build_base
    if not changes:
        (full_path, changes) = re.subn('^BUILD', build_base, path)
    if not changes:
        raise Exception('Unknown pattern type: %s' % path)
    folder = None
    if full_path.endswith(name):
        folder = os.path.relpath(full_path[:-len(name)], FUCHSIA_ROOT)
    file = os.path.relpath(full_path, FUCHSIA_ROOT)
    return (file, folder)


def filter_deps(deps):
    '''Sanitizes a given dependency list.'''
    return filter(lambda x: x not in SYSROOT_PACKAGES, deps)


def filter_sdk_deps(deps):
    '''Sanitizes a given SDK dependency list.'''
    return filter(lambda x: x not in NON_SDK_DEPS, deps)


def generate_build_file(path, template_name, data, context):
    '''Creates a build file based on a template.'''
    make_dir(path)
    template = context.templates.get_template(template_name)
    contents = template.render(data=data)
    with open(path, 'w') as build_file:
        build_file.write(contents)


class SourceLibrary(object):
    '''Represents a library built from sources.

       Convenience storage object to be consumed by Mako templates.'''

    def __init__(self, name):
        self.name = name
        self.includes = {}
        self.include_dirs = set()
        self.sources = {}
        self.deps = []
        self.sdk_deps = []
        self.fidl_deps = []
        self.banjo_deps = []
        self.libs = set()
        self.depends_on_zircon = False


def generate_source_library(package, context):
    '''Generates the build glue for a library whose sources are provided.'''
    lib_name = package['package']['name']
    data = SourceLibrary(lib_name)

    # Includes.
    for name, path in package.get('includes', {}).iteritems():
        (file, folder) = extract_file(name, path, context)
        data.includes[name] = '//%s' % file
        data.include_dirs.add('//%s' % folder)
        if lib_name in LIBRARIES_BEING_MOVED:
            data.include_dirs.add('//%s/lib' % folder)

    # Source files.
    for name, path in package.get('src', {}).iteritems():
        (file, _) = extract_file(name, path, context)
        data.sources[name] = '//%s' % file

    # Dependencies.
    data.deps += filter_deps(package.get('deps', []))
    data.deps += filter_deps(package.get('static-deps', []))
    data.fidl_deps = filter_deps(package.get('fidl-deps', []))
    data.banjo_deps = filter_deps(package.get('banjo-deps', []))
    data.sdk_deps = filter_sdk_deps(data.deps)

    # Special hack for zircon library dependency: enables special codegen
    # in template depending on whether we're building on Fuchsia or not.
    data.depends_on_zircon = 'zircon' in package.get('deps', [])

    # Generate the build file.
    build_path = os.path.join(context.out_dir, 'lib', lib_name, 'BUILD.gn')
    generate_build_file(build_path, 'source_library.mako', data, context)


class CompiledLibrary(object):
    '''Represents a library already compiled by the Zircon build.

       Convenience storage object to be consumed by Mako templates.'''

    def __init__(self, name, with_sdk_headers):
        self.name = name
        self.includes = {}
        self.include_dirs = set()
        self.deps = []
        self.sdk_deps = []
        self.fidl_deps = []
        self.banjo_deps = []
        self.lib_name = ''
        self.has_impl_prebuilt = False
        self.impl_prebuilt = ''
        self.prebuilt = ''
        self.debug_prebuilt = ''
        self.with_sdk_headers = with_sdk_headers


def generate_compiled_library(package, context):
    '''Generates the build glue for a prebuilt library.'''
    lib_name = package['package']['name']
    data = CompiledLibrary(lib_name,
                           lib_name not in LIBRARIES_WITHOUT_SDK_HEADERS)

    # Includes.
    for name, path in package.get('includes', {}).iteritems():
        (file, folder) = extract_file(name, path, context)
        data.include_dirs.add('//%s' % folder)
        data.includes[name] = '//%s' % file

    # Lib.
    libs = package.get('lib', {})
    if len(libs) == 1:
        # Static library.
        is_shared = False
        (name, path) = libs.items()[0]
        (file, _) = extract_file(name, path, context)
        data.prebuilt = '//%s' % file
        data.lib_name = os.path.basename(name)
    # TODO(jamesr): Delete the == 2 path once Zircon rolls up through all layers
    elif len(libs) == 2 or len(libs) == 3:
        # Shared library.
        is_shared = True
        for name, path in libs.iteritems():
            (file, _) = extract_file(name, path, context)
            if 'debug/' in name:
                data.debug_prebuilt = '//%s' % file
                data.lib_name = os.path.basename(name)
            elif '.so.strip' in file:
                data.has_impl_prebuilt = True
                data.impl_prebuilt = '//%s' % file
            else:
                data.prebuilt = '//%s' % file
    else:
        raise Exception('Too many files for %s: %s' % (lib_name,
                                                       ', '.join(libs.keys())))

    # Dependencies.
    data.deps += filter_deps(package.get('deps', []))
    data.deps += filter_deps(package.get('static-deps', []))
    data.fidl_deps = filter_deps(package.get('fidl-deps', []))
    data.banjo_deps = filter_deps(package.get('banjo-deps', []))
    data.sdk_deps = filter_sdk_deps(data.deps)

    # Generate the build file.
    template = 'shared_library.mako' if is_shared else 'static_library.mako'
    build_path = os.path.join(context.out_dir, 'lib', lib_name, 'BUILD.gn')
    generate_build_file(build_path, template, data, context)


class Sysroot(object):
    '''Represents the sysroot created by Zircon.

       Convenience storage object to be consumed by Mako templates.'''

    def __init__(self):
        self.files = {}
        self.sdk_files = {}
        self.headers = []
        self.link_libs = []
        self.dist_libs = []
        self.debug_source_libs = []


def generate_sysroot(package, context):
    '''Generates the build glue for the sysroot.'''
    data = Sysroot()

    # Includes.
    for name, path in package.get('includes', {}).iteritems():
        (file, _) = extract_file(name, path, context)
        data.files['include/%s' % name] = '//%s' % file
        in_sdk = True
        for prefix in NON_SDK_SYSROOT_HEADER_PREFIXES:
            if name.startswith(prefix) and name not in MANDATORY_SDK_HEADERS:
                in_sdk = False
                break
        if in_sdk:
            dest = 'include/%s' % name
            data.sdk_files[dest] = '//%s' % file
            data.headers.append(dest)

    # Lib.
    for name, path in package.get('lib', {}).iteritems():
        (file, _) = extract_file(name, path, context)
        label = '//%s' % file
        data.files[name] = label
        type_dir = os.path.dirname(name)
        if type_dir == 'debug':
            data.debug_source_libs.append(label)
        else:
            data.sdk_files[name] = label
            if type_dir == 'lib':
                data.link_libs.append(name)
            elif type_dir == 'dist/lib':
                data.dist_libs.append(name)
            else:
                raise Exception('Unknown library type: ' + type_dir)

    # Generate the build file.
    build_path = os.path.join(context.out_dir, 'sysroot', 'BUILD.gn')
    generate_build_file(build_path, 'sysroot.mako', data, context)


class HostTool(object):
    '''Represents a host tool.

       Convenience storage object to be consumed by Mako templates.'''

    def __init__(self, name):
        self.name = name
        self.executable = ''


def generate_host_tool(package, context):
    '''Generates the build glue for a host tool.'''
    name = package['package']['name']
    data = HostTool(name)

    bins = package.get('bin', {})
    if len(bins) != 1 or name not in bins:
        raise Exception('Host tool %s has unexpected binaries %s.'
                        % (name, bins))
    (file, _) = extract_file(name, bins[name], context, is_tool=True)
    data.executable = '//%s' % file

    # Generate the build file.
    build_path = os.path.join(context.out_dir, 'tool', name, 'BUILD.gn')
    generate_build_file(build_path, 'host_tool.mako', data, context)


class FidlLibrary(object):
    '''Represents a FIDL library.

       Convenience storage object to be consumed by Mako templates.'''

    def __init__(self, name, library):
        self.name = name
        self.library = library
        self.sources = []
        self.fidl_deps = []


def generate_fidl_library(package, context):
    '''Generates the build glue for a FIDL library.'''
    pkg_name = package['package']['name']
    # TODO(pylaligand): remove fallback.
    data = FidlLibrary(pkg_name, package['package'].get('library', pkg_name))

    for name, path in package.get('fidl', {}).iteritems():
        (file, _) = extract_file(name, path, context)
        data.sources.append('//%s' % file)
    data.fidl_deps = filter_deps(package.get('fidl-deps', []))

    # Generate the build file.
    build_path = os.path.join(context.out_dir, 'fidl', pkg_name, 'BUILD.gn')
    generate_build_file(build_path, 'fidl.mako', data, context)


class BanjoLibrary(object):
    '''Represents a Banjo library.

       Convenience storage object to be consumed by Mako templates.'''

    def __init__(self, name, library):
        self.name = name
        self.library = library
        self.sources = []
        self.banjo_deps = []


def generate_banjo_dummy_library(package, context):
    '''Generates the build glue for a dummy Banjo library.'''
    pkg_name = package['package']['name']

    data  = BanjoLibrary(pkg_name, package['package']['library'])

    for name, path in package.get('banjo', {}).iteritems():
        (file, _) = extract_file(name, path, context)
        data.sources.append('//%s' % file)

    # Generate the build file.
    build_path = os.path.join(context.out_dir, 'banjo', pkg_name, 'BUILD.gn')
    generate_build_file(build_path, 'banjo_dummy.mako', data, context)

def generate_banjo_library(package, context):
    '''Generates the build glue for a Banjo library.'''
    pkg_name = package['package']['name']

    if "ddk-protocol" not in pkg_name:
        generate_banjo_dummy_library(package, context)
        return

    data  = BanjoLibrary(pkg_name, package['package']['library'])

    for name, path in package.get('banjo', {}).iteritems():
        (file, _) = extract_file(name, path, context)
        data.sources.append('//%s' % file)
    data.banjo_deps = filter_deps(package.get('banjo-deps', []))
    data.deps = [
        '//zircon/public/lib/ddk',
        '//zircon/public/lib/ddktl',
    ]

    # Generate the build file.
    build_path = os.path.join(context.out_dir, 'banjo', pkg_name, 'BUILD.gn')
    generate_build_file(build_path, 'banjo.mako', data, context)


def generate_board_list(package, context):
    '''Generates a configuration file with the list of target boards.'''
    build_path = os.path.join(context.out_dir, 'config', 'boards.gni')
    generate_build_file(build_path, 'boards.mako', package, context)
    build_path = os.path.join(context.out_dir, 'config', 'BUILD.gn')
    generate_build_file(build_path, 'main.mako', package, context)


class GenerationContext(object):
    '''Describes the context in which GN rules should be generated.'''

    def __init__(self, out_dir, source_base, user_build_base, tool_build_base,
                 templates):
        self.out_dir = out_dir
        self.source_base = source_base
        self.user_build_base = user_build_base
        self.tool_build_base = tool_build_base
        self.templates = templates


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--out',
                        help='Path to the output directory',
                        required=True)
    parser.add_argument('--staging',
                        help='Path to the staging directory',
                        required=True)
    parser.add_argument('--zircon-user-build',
                        help='Path to the Zircon "user" build directory',
                        required=True)
    parser.add_argument('--zircon-tool-build',
                        help='Path to the Zircon "tools" build directory',
                        required=True)
    parser.add_argument('--debug',
                        help='Whether to print out debug information',
                        action='store_true')
    parser.add_argument('--make',
                        help='Path to make binary',
                        required=True)
    args = parser.parse_args()

    out_dir = os.path.abspath(args.out)
    shutil.rmtree(os.path.join(out_dir, 'config'), True)
    shutil.rmtree(os.path.join(out_dir, 'fidl'), True)
    shutil.rmtree(os.path.join(out_dir, 'banjo'), True)
    shutil.rmtree(os.path.join(out_dir, 'lib'), True)
    shutil.rmtree(os.path.join(out_dir, 'sysroot'), True)
    shutil.rmtree(os.path.join(out_dir, 'tool'), True)
    debug = args.debug

    # Generate package descriptions through Zircon's build.
    zircon_dir = os.path.abspath(args.staging)
    shutil.rmtree(zircon_dir, True)
    if debug:
        print('Building Zircon in: %s' % zircon_dir)
    make_args = [
        args.make,
        'packages',
        'BUILDDIR=%s' % zircon_dir,
    ]

    env = {}
    env['PATH'] = os.environ['PATH']
    if not debug:
        env['QUIET'] = '1'
    subprocess.check_call(make_args, cwd=ZIRCON_ROOT, env=env)
    # Parse package definitions.
    packages = []
    with open(os.path.join(zircon_dir, 'export', 'manifest'), 'r') as manifest:
        package_files = map(lambda line: line.strip(), manifest.readlines())
    for file in package_files:
        with open(os.path.join(zircon_dir, 'export', file), 'r') as pkg_file:
            packages.append(parse_package(pkg_file.readlines()))
    if debug:
        print('Found %s packages:' % len(packages))
        names = sorted(map(lambda p: p['package']['name'], packages))
        for name in names:
            print(' - %s' % name)

    # Generate some GN glue for each package.
    context = GenerationContext(
        out_dir,
        ZIRCON_ROOT,
        os.path.abspath(args.zircon_user_build),
        os.path.abspath(args.zircon_tool_build),
        TemplateLookup(directories=[SCRIPT_DIR]),
    )
    for package in packages:
        name = package['package']['name']
        type = package['package']['type']
        arch = package['package']['arch']
        if name == 'c':
            generate_sysroot(package, context)
            print('Generated sysroot')
            continue
        if name in SYSROOT_PACKAGES:
            print('Ignoring sysroot part: %s' % name)
            continue
        if type == 'tool':
            generate_host_tool(package, context)
        elif type == 'lib':
            if arch == 'src':
                type = 'source'
                generate_source_library(package, context)
            else:
                type = 'prebuilt'
                generate_compiled_library(package, context)
        elif type == 'fidl':
            generate_fidl_library(package, context)
        elif type == 'banjo':
            generate_banjo_library(package, context)
        else:
            print('(%s) Unsupported package type: %s/%s, skipping'
                  % (name, type, arch))
            continue
        if debug:
            print('Processed %s (%s)' % (name, type))

    board_path = os.path.join(zircon_dir, 'export', 'all-boards.list')
    with open(board_path, 'r') as board_file:
        package = parse_package(board_file.readlines())
        generate_board_list(package, context)


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