#!/usr/bin/env python3

#  Copyright 2021 Google, Inc.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at:
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
""" Build BT targets on the host system.

For building, you will first have to stage a platform directory that has the
following structure:
|-common-mk
|-bt
|-external
|-|-rust
|-|-|-vendor

The simplest way to do this is to check out platform2 to another directory (that
is not a subdir of this bt directory), symlink bt there and symlink the rust
vendor repository as well.
"""
import argparse
import multiprocessing
import os
import shutil
import six
import subprocess
import sys

# Use flags required by common-mk (find -type f | grep -nE 'use[.]' {})
COMMON_MK_USES = [
    'asan',
    'coverage',
    'cros_host',
    'fuzzer',
    'fuzzer',
    'msan',
    'profiling',
    'tcmalloc',
    'test',
    'ubsan',
]

# Default use flags.
USE_DEFAULTS = {
    'android': False,
    'bt_nonstandard_codecs': False,
    'test': False,
}

VALID_TARGETS = [
    'prepare',  # Prepare the output directory (gn gen + rust setup)
    'tools',  # Build the host tools (i.e. packetgen)
    'rust',  # Build only the rust components + copy artifacts to output dir
    'main',  # Build the main C++ codebase
    'test',  # Run the unit tests
    'clean',  # Clean up output directory
    'all',  # All targets except test and clean
]

# TODO(b/190750167) - Host tests are disabled until we are full bazel build
HOST_TESTS = [
    # 'bluetooth_test_common',
    # 'bluetoothtbd_test',
    # 'net_test_avrcp',
    # 'net_test_btcore',
    # 'net_test_types',
    # 'net_test_btm_iso',
    # 'net_test_btpackets',
]


class UseFlags():

    def __init__(self, use_flags):
        """ Construct the use flags.

        Args:
            use_flags: List of use flags parsed from the command.
        """
        self.flags = {}

        # Import use flags required by common-mk
        for use in COMMON_MK_USES:
            self.set_flag(use, False)

        # Set our defaults
        for use, value in USE_DEFAULTS.items():
            self.set_flag(use, value)

        # Set use flags - value is set to True unless the use starts with -
        # All given use flags always override the defaults
        for use in use_flags:
            value = not use.startswith('-')
            self.set_flag(use, value)

    def set_flag(self, key, value=True):
        setattr(self, key, value)
        self.flags[key] = value


class HostBuild():

    def __init__(self, args):
        """ Construct the builder.

        Args:
            args: Parsed arguments from ArgumentParser
        """
        self.args = args

        # Set jobs to number of cpus unless explicitly set
        self.jobs = self.args.jobs
        if not self.jobs:
            self.jobs = multiprocessing.cpu_count()
            print("Number of jobs = {}".format(self.jobs))

        # Normalize all directories
        self.output_dir = os.path.abspath(self.args.output)
        self.platform_dir = os.path.abspath(self.args.platform_dir)
        self.sysroot = self.args.sysroot
        self.use_board = os.path.abspath(self.args.use_board) if self.args.use_board else None
        self.libdir = self.args.libdir

        # If default target isn't set, build everything
        self.target = 'all'
        if hasattr(self.args, 'target') and self.args.target:
            self.target = self.args.target

        target_use = self.args.use if self.args.use else []

        # Unless set, always build test code
        if not self.args.notest:
            target_use.append('test')

        self.use = UseFlags(target_use)

        # Validate platform directory
        assert os.path.isdir(self.platform_dir), 'Platform dir does not exist'
        assert os.path.isfile(os.path.join(self.platform_dir, '.gn')), 'Platform dir does not have .gn at root'

        # Make sure output directory exists (or create it)
        os.makedirs(self.output_dir, exist_ok=True)

        # Set some default attributes
        self.libbase_ver = None

        self.configure_environ()

    def _generate_rustflags(self):
        """ Rustflags to include for the build.
      """
        rust_flags = [
            '-L',
            '{}/out/Default/'.format(self.output_dir),
            '-C',
            'link-arg=-Wl,--allow-multiple-definition',
        ]

        return ' '.join(rust_flags)

    def configure_environ(self):
        """ Configure environment variables for GN and Cargo.
        """
        self.env = os.environ.copy()

        # Make sure cargo home dir exists and has a bin directory
        cargo_home = os.path.join(self.output_dir, 'cargo_home')
        os.makedirs(cargo_home, exist_ok=True)
        os.makedirs(os.path.join(cargo_home, 'bin'), exist_ok=True)

        # Configure Rust env variables
        self.env['CARGO_TARGET_DIR'] = self.output_dir
        self.env['CARGO_HOME'] = os.path.join(self.output_dir, 'cargo_home')
        self.env['RUSTFLAGS'] = self._generate_rustflags()
        self.env['CXX_ROOT_PATH'] = os.path.join(self.platform_dir, 'bt')

        # Configure some GN variables
        if self.use_board:
            self.env['PKG_CONFIG_PATH'] = os.path.join(self.use_board, self.libdir, 'pkgconfig')
            libdir = os.path.join(self.use_board, self.libdir)
            if self.env.get('LIBRARY_PATH'):
                libpath = self.env['LIBRARY_PATH']
                self.env['LIBRARY_PATH'] = '{}:{}'.format(libdir, libpath)
            else:
                self.env['LIBRARY_PATH'] = libdir

    def run_command(self, target, args, cwd=None, env=None):
        """ Run command and stream the output.
        """
        # Set some defaults
        if not cwd:
            cwd = self.platform_dir
        if not env:
            env = self.env

        log_file = os.path.join(self.output_dir, '{}.log'.format(target))
        with open(log_file, 'wb') as lf:
            rc = 0
            process = subprocess.Popen(args, cwd=cwd, env=env, stdout=subprocess.PIPE)
            while True:
                line = process.stdout.readline()
                print(line.decode('utf-8'), end="")
                lf.write(line)
                if not line:
                    rc = process.poll()
                    if rc is not None:
                        break

                    time.sleep(0.1)

            if rc != 0:
                raise Exception("Return code is {}".format(rc))

    def _get_basever(self):
        if self.libbase_ver:
            return self.libbase_ver

        self.libbase_ver = os.environ.get('BASE_VER', '')
        if not self.libbase_ver:
            base_file = os.path.join(self.sysroot, 'usr/share/libchrome/BASE_VER')
            try:
                with open(base_file, 'r') as f:
                    self.libbase_ver = f.read().strip('\n')
            except:
                self.libbase_ver = 'NOT-INSTALLED'

        return self.libbase_ver

    def _gn_default_output(self):
        return os.path.join(self.output_dir, 'out/Default')

    def _gn_configure(self):
        """ Configure all required parameters for platform2.

        Mostly copied from //common-mk/platform2.py
        """
        clang = self.args.clang

        def to_gn_string(s):
            return '"%s"' % s.replace('"', '\\"')

        def to_gn_list(strs):
            return '[%s]' % ','.join([to_gn_string(s) for s in strs])

        def to_gn_args_args(gn_args):
            for k, v in gn_args.items():
                if isinstance(v, bool):
                    v = str(v).lower()
                elif isinstance(v, list):
                    v = to_gn_list(v)
                elif isinstance(v, six.string_types):
                    v = to_gn_string(v)
                else:
                    raise AssertionError('Unexpected %s, %r=%r' % (type(v), k, v))
                yield '%s=%s' % (k.replace('-', '_'), v)

        gn_args = {
            'platform_subdir': 'bt',
            'cc': 'clang' if clang else 'gcc',
            'cxx': 'clang++' if clang else 'g++',
            'ar': 'llvm-ar' if clang else 'ar',
            'pkg-config': 'pkg-config',
            'clang_cc': clang,
            'clang_cxx': clang,
            'OS': 'linux',
            'sysroot': self.sysroot,
            'libdir': os.path.join(self.sysroot, self.libdir),
            'build_root': self.output_dir,
            'platform2_root': self.platform_dir,
            'libbase_ver': self._get_basever(),
            'enable_exceptions': os.environ.get('CXXEXCEPTIONS', 0) == '1',
            'external_cflags': [],
            'external_cxxflags': [],
            'enable_werror': False,
        }

        if clang:
            # Make sure to mark the clang use flag as true
            self.use.set_flag('clang', True)
            gn_args['external_cxxflags'] += ['-I/usr/include/']

        # EXTREME HACK ALERT
        #
        # In my laziness, I am supporting building against an already built
        # sysroot path (i.e. chromeos board) so that I don't have to build
        # libchrome or modp_b64 locally.
        if self.use_board:
            includedir = os.path.join(self.use_board, 'usr/include')
            gn_args['external_cxxflags'] += [
                '-I{}'.format(includedir),
                '-I{}/libchrome'.format(includedir),
                '-I{}/gtest'.format(includedir),
                '-I{}/gmock'.format(includedir),
                '-I{}/modp_b64'.format(includedir),
            ]
        gn_args_args = list(to_gn_args_args(gn_args))
        use_args = ['%s=%s' % (k, str(v).lower()) for k, v in self.use.flags.items()]
        gn_args_args += ['use={%s}' % (' '.join(use_args))]

        gn_args = [
            'gn',
            'gen',
        ]

        if self.args.verbose:
            gn_args.append('-v')

        gn_args += [
            '--root=%s' % self.platform_dir,
            '--args=%s' % ' '.join(gn_args_args),
            self._gn_default_output(),
        ]

        if 'PKG_CONFIG_PATH' in self.env:
            print('DEBUG: PKG_CONFIG_PATH is', self.env['PKG_CONFIG_PATH'])

        self.run_command('configure', gn_args)

    def _gn_build(self, target):
        """ Generate the ninja command for the target and run it.
        """
        args = ['%s:%s' % ('bt', target)]
        ninja_args = ['ninja', '-C', self._gn_default_output()]
        if self.jobs:
            ninja_args += ['-j', str(self.jobs)]
        ninja_args += args

        if self.args.verbose:
            ninja_args.append('-v')

        self.run_command('build', ninja_args)

    def _rust_configure(self):
        """ Generate config file at cargo_home so we use vendored crates.
        """
        template = """
        [source.systembt]
        directory = "{}/external/rust/vendor"

        [source.crates-io]
        replace-with = "systembt"
        local-registry = "/nonexistent"
        """

        if self.args.vendored_rust:
            contents = template.format(self.platform_dir)
            with open(os.path.join(self.env['CARGO_HOME'], 'config'), 'w') as f:
                f.write(contents)

    def _rust_build(self):
        """ Run `cargo build` from platform2/bt directory.
        """
        self.run_command('rust', ['cargo', 'build'], cwd=os.path.join(self.platform_dir, 'bt'), env=self.env)

    def _target_prepare(self):
        """ Target to prepare the output directory for building.

        This runs gn gen to generate all rquired files and set up the Rust
        config properly. This will be run
        """
        self._gn_configure()
        self._rust_configure()

    def _target_tools(self):
        """ Build the tools target in an already prepared environment.
        """
        self._gn_build('tools')

        # Also copy bluetooth_packetgen to CARGO_HOME so it's available
        shutil.copy(
            os.path.join(self._gn_default_output(), 'bluetooth_packetgen'), os.path.join(self.env['CARGO_HOME'], 'bin'))

    def _target_rust(self):
        """ Build rust artifacts in an already prepared environment.
        """
        self._rust_build()
        rust_dir = os.path.join(self._gn_default_output(), 'rust')
        if os.path.exists(rust_dir):
            shutil.rmtree(rust_dir)
        shutil.copytree(os.path.join(self.output_dir, 'debug'), rust_dir)

    def _target_main(self):
        """ Build the main GN artifacts in an already prepared environment.
        """
        self._gn_build('all')

    def _target_test(self):
        """ Runs the host tests.
        """
        # Rust tests first
        self.run_command('test', ['cargo', 'test'], cwd=os.path.join(self.platform_dir, 'bt'), env=self.env)

        # Host tests second based on host test list
        for t in HOST_TESTS:
            self.run_command(
                'test', [os.path.join(self.output_dir, 'out/Default', t)],
                cwd=os.path.join(self.output_dir),
                env=self.env)

    def _target_clean(self):
        """ Delete the output directory entirely.
        """
        shutil.rmtree(self.output_dir)

    def _target_all(self):
        """ Build all common targets (skipping test and clean).
        """
        self._target_prepare()
        self._target_tools()
        self._target_main()
        self._target_rust()

    def build(self):
        """ Builds according to self.target
        """
        print('Building target ', self.target)

        if self.target == 'prepare':
            self._target_prepare()
        elif self.target == 'tools':
            self._target_tools()
        elif self.target == 'rust':
            self._target_rust()
        elif self.target == 'main':
            self._target_main()
        elif self.target == 'test':
            self._target_test()
        elif self.target == 'clean':
            self._target_clean()
        elif self.target == 'all':
            self._target_all()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Simple build for host.')
    parser.add_argument('--output', help='Output directory for the build.', required=True)
    parser.add_argument('--platform-dir', help='Directory where platform2 is staged.', required=True)
    parser.add_argument('--clang', help='Use clang compiler.', default=False, action='store_true')
    parser.add_argument('--use', help='Set a specific use flag.')
    parser.add_argument('--notest', help="Don't compile test code.", default=False, action='store_true')
    parser.add_argument('--target', help='Run specific build target')
    parser.add_argument('--sysroot', help='Set a specific sysroot path', default='/')
    parser.add_argument('--libdir', help='Libdir - default = usr/lib64', default='usr/lib64')
    parser.add_argument('--use-board', help='Use a built x86 board for dependencies. Provide path.')
    parser.add_argument('--jobs', help='Number of jobs to run', default=0, type=int)
    parser.add_argument('--vendored-rust', help='Use vendored rust crates', default=False, action='store_true')
    parser.add_argument('--verbose', help='Verbose logs for build.')

    args = parser.parse_args()
    build = HostBuild(args)
    build.build()
