#!/usr/bin/env python
# Copyright 2018 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 os
import shutil
import stat
import sys

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
FUCHSIA_ROOT = os.path.dirname(  # $root
    os.path.dirname(             # scripts
    os.path.dirname(             # sdk
    SCRIPT_DIR)))                # bazel

sys.path += [os.path.join(FUCHSIA_ROOT, 'third_party', 'mako')]
from mako.lookup import TemplateLookup
from mako.template import Template
sys.path += [os.path.join(FUCHSIA_ROOT, 'scripts', 'sdk', 'common')]
from frontend import Frontend
from files import copy_tree

from create_test_workspace import create_test_workspace, SdkWorkspaceInfo
import template_model as model


def sanitize(name):
    return name.replace('-', '_').replace('.', '_')


class BazelBuilder(Frontend):

    def __init__(self, **kwargs):
        super(BazelBuilder, self).__init__(**kwargs)
        self.has_dart = False
        self.has_cc = False
        self.dart_vendor_packages = {}
        self.target_arches = []
        self.workspace_info = SdkWorkspaceInfo()


    def _copy_file(self, file, root, destination, result=[]):
        '''Copies the file from a given root directory and writes the
        resulting relative paths to a list.
        '''
        if os.path.commonprefix([root, file]) != root:
            raise Exception('%s is not within %s' % (file, root))
        relative_path = os.path.relpath(file, root)
        dest = self.dest(destination, relative_path)
        shutil.copy2(self.source(file), dest)
        result.append(relative_path)


    def _copy_files(self, files, root, destination, result=[]):
        '''Copies some files from a given root directory and writes the
        resulting relative paths to a list.
        '''
        for file in files:
            self._copy_file(file, root, destination, result)


    def local(self, *args):
        '''Builds a path in the current directory.'''
        return os.path.join(SCRIPT_DIR, *args)


    def write_file(self, path, template_name, data):
        '''Writes a file based on a Mako template.'''
        lookup = TemplateLookup(directories=[self.local('templates')])
        template = lookup.get_template(template_name + '.mako')
        with open(path, 'w') as file:
            file.write(template.render(data=data))


    def add_dart_vendor_package(self, name, version):
        '''Adds a reference to a new Dart third-party package.'''
        if name == 'flutter' and version == 'flutter_sdk':
            # The Flutter SDK is set up separately.
            return
        if name in self.dart_vendor_packages:
            existing_version = self.dart_vendor_packages[name]
            if existing_version != version:
                raise Exception('Dart package %s can only have one version; '
                                '%s and %s requested.' % (name, version,
                                                          existing_version))
        else:
            self.dart_vendor_packages[name] = version


    def prepare(self, arch, types):
        self.target_arches = arch['target']

        # Copy the common files.
        shutil.copytree(self.local('base', 'common'), self.output)
        # Copy C/C++ files if needed.
        if ('sysroot' in types or 'cc_source_library' in types or
            'cc_prebuilt_library' in types):
            self.has_cc = True
            copy_tree(self.local('base', 'cc'), self.output)
        # Copy Dart files if needed.
        if 'dart_library' in types:
            self.has_dart = True
            copy_tree(self.local('base', 'dart'), self.output)

        self.install_crosstool(arch)

        self.workspace_info.with_cc = self.has_cc
        self.workspace_info.with_dart = self.has_dart
        self.workspace_info.target_arches = self.target_arches


    def finalize(self, arch, types):
        self.install_tools()
        self.install_dart()


    def install_tools(self):
        '''Write BUILD files for tools directories.'''
        tools_root = os.path.join(self.output, 'tools')
        for directory, _, _ in os.walk(tools_root, topdown=True):
            self.write_file(os.path.join(directory, 'BUILD'), 'tools', {})


    def install_crosstool(self, arches):
        '''Generates crosstool.bzl based on the availability of sysroot
        versions.
        '''
        if not self.has_cc:
            return
        crosstool = model.Crosstool(arches['target'])
        self.write_file(self.dest('build_defs', 'crosstool.bzl'),
                        'crosstool_bzl', crosstool)
        self.write_file(self.dest('build_defs', 'BUILD.crosstool'),
                        'crosstool', crosstool)
        self.write_file(self.dest('build_defs', 'CROSSTOOL.in'),
                        'crosstool_in', crosstool)
        self.write_file(self.dest('build_defs', 'toolchain', 'BUILD'),
                        'toolchain_build', crosstool)


    def install_dart(self):
        if not self.has_dart:
            return
        # Write the rule for setting up Dart packages.
        # TODO(pylaligand): this process currently does not capture dependencies
        # between vendor packages.
        self.write_file(self.dest('build_defs', 'setup_dart.bzl'),
                       'setup_dart_bzl', self.dart_vendor_packages)


    def install_dart_library_atom(self, atom):
        package_name = atom['name']
        name = sanitize(package_name)
        library = model.DartLibrary(name, package_name)
        base = self.dest('dart', name)

        self._copy_files(atom['sources'], atom['root'], base)

        for dep in atom['deps']:
            library.deps.append('//dart/' + sanitize(dep))

        for dep in atom['fidl_deps']:
            san_dep = sanitize(dep)
            library.deps.append('//fidl/%s:%s_dart' % (san_dep, san_dep))

        for dep in atom['third_party_deps']:
            name = dep['name']
            library.deps.append('@vendor_%s//:%s' % (name, name))
            self.add_dart_vendor_package(name, dep['version'])

        self.write_file(os.path.join(base, 'BUILD'), 'dart_library', library)


    def install_cc_prebuilt_library_atom(self, atom):
        name = sanitize(atom['name'])
        library = model.CppPrebuiltLibrary(name)
        library.is_static = atom['format'] == 'static'
        base = self.dest('pkg', name)

        self._copy_files(atom['headers'], atom['root'], base, library.hdrs)

        for arch in self.target_arches:
            def _copy_prebuilt(path, category):
                relative_dest = os.path.join('arch', arch, category,
                                             os.path.basename(path))
                dest = self.dest(base, relative_dest)
                shutil.copy2(self.source(path), dest)
                return relative_dest

            binaries = atom['binaries'][arch]
            prebuilt_set = model.CppPrebuiltSet(_copy_prebuilt(binaries['link'],
                                                              'lib'))
            if 'dist' in binaries:
                dist = binaries['dist']
                prebuilt_set.dist_lib = _copy_prebuilt(dist, 'dist')
                prebuilt_set.dist_path = 'lib/' + os.path.basename(dist)

            library.prebuilts[arch] = prebuilt_set

        for dep in atom['deps']:
            library.deps.append('//pkg/' + sanitize(dep))

        library.includes = os.path.relpath(atom['include_dir'], atom['root'])

        include_paths = map(lambda h: os.path.relpath(h, atom['include_dir']),
                            atom['headers'])
        self.workspace_info.headers['//pkg/' + name] = include_paths

        self.write_file(os.path.join(base, 'BUILD'), 'cc_prebuilt_library',
                        library)


    def install_cc_source_library_atom(self, atom):
        name = sanitize(atom['name'])
        library = model.CppSourceLibrary(name)
        base = self.dest('pkg', name)

        self._copy_files(atom['headers'], atom['root'], base, library.hdrs)
        self._copy_files(atom['sources'], atom['root'], base, library.srcs)

        for dep in atom['deps']:
            library.deps.append('//pkg/' + sanitize(dep))

        for dep in atom['fidl_deps']:
            dep_name = sanitize(dep)
            library.deps.append('//fidl/%s:%s_cc' % (dep_name, dep_name))

        library.includes = os.path.relpath(atom['include_dir'], atom['root'])

        include_paths = map(lambda h: os.path.relpath(h, atom['include_dir']),
                            atom['headers'])
        self.workspace_info.headers['//pkg/' + name] = include_paths

        self.write_file(os.path.join(base, 'BUILD'), 'cc_library', library)


    def install_sysroot_atom(self, atom):
        for arch in self.target_arches:
            base = self.dest('arch', arch, 'sysroot')
            arch_data = atom['versions'][arch]
            self._copy_files(arch_data['headers'], arch_data['root'], base)
            self._copy_files(arch_data['link_libs'], arch_data['root'], base)
            self._copy_files(arch_data['debug_libs'], arch_data['root'], base)
            dist_libs = []
            self._copy_files(arch_data['dist_libs'], arch_data['root'], base,
                             dist_libs)
            version = {}
            for lib in dist_libs:
                version['lib/' + os.path.basename(lib)] = lib
            self.write_file(os.path.join(base, 'BUILD'), 'sysroot_version',
                            version)

        self.write_file(self.dest('pkg', 'sysroot', 'BUILD'),
                        'sysroot_pkg', self.target_arches)


    def install_host_tool_atom(self, atom):
        self._copy_files(atom['files'], atom['root'], 'tools')


    def install_fidl_library_atom(self, atom):
        name = sanitize(atom['name'])
        data = model.FidlLibrary(name, atom['name'])
        data.with_cc = self.has_cc
        data.with_dart = self.has_dart
        base = self.dest('fidl', name)
        self._copy_files(atom['sources'], atom['root'], base, data.srcs)
        for dep in atom['deps']:
            data.deps.append(sanitize(dep))
        self.write_file(os.path.join(base, 'BUILD'), 'fidl', data)


    def install_image_atom(self, atom):
        # 'image_file' contains a relative path that is good enough to be stored
        # under the top-level SDK directory. No 'root' or 'destination' is
        # needed.
        root = ''
        dest = ''
        target_architectures = {}
        for image_file in atom['file'].itervalues():
            self._copy_file(image_file, root, dest)
            # The image file looks like this: target/x64/fuchsia.zbi
            # where x64 is the architecture
            target, arch = os.path.split(os.path.dirname(image_file))
            if target not in target_architectures:
                target_architectures[target] = set()
            target_architectures[target].add(arch)

        for target in target_architectures:
            data = model.Images(list(target_architectures[target]))
            self.write_file(self.dest(os.path.join(target, 'BUILD')), 'images',
                            data)


def main():
    parser = argparse.ArgumentParser(
            description='Lays out a Bazel workspace for a given SDK tarball.')
    source_group = parser.add_mutually_exclusive_group(required=True)
    source_group.add_argument('--archive',
                              help='Path to the SDK archive to ingest',
                              default='')
    source_group.add_argument('--directory',
                              help='Path to the SDK directory to ingest',
                              default='')
    parser.add_argument('--output',
                        help='Path to the directory where to install the SDK',
                        required=True)
    parser.add_argument('--tests',
                        help='Path to the directory where to generate tests')
    args = parser.parse_args()

    # Remove any existing output.
    shutil.rmtree(args.output, ignore_errors=True)

    builder = BazelBuilder(archive=args.archive,
                           directory=args.directory,
                           output=args.output)
    if not builder.run():
        return 1

    if args.tests and not create_test_workspace(args.output, args.tests,
                                                builder.workspace_info):
        return 1

    return 0


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