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

# 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',
]

BOOTSTRAP_GIT_REPOS = {
    'platform2': 'https://chromium.googlesource.com/chromiumos/platform2',
    'rust_crates': 'https://chromium.googlesource.com/chromiumos/third_party/rust_crates',
    'proto_logging': 'https://android.googlesource.com/platform/frameworks/proto_logging'
}

# List of packages required for linux build
REQUIRED_APT_PACKAGES = [
    'bison',
    'build-essential',
    'curl',
    'debmake',
    'flatbuffers-compiler',
    'flex',
    'g++-multilib',
    'gcc-multilib',
    'generate-ninja',
    'gnupg',
    'gperf',
    'libc++-dev',
    'libdbus-1-dev',
    'libevent-dev',
    'libevent-dev',
    'libflatbuffers-dev',
    'libflatbuffers1',
    'libgl1-mesa-dev',
    'libglib2.0-dev',
    'liblz4-tool',
    'libncurses5',
    'libnss3-dev',
    'libprotobuf-dev',
    'libre2-9',
    'libssl-dev',
    'libtinyxml2-dev',
    'libx11-dev',
    'libxml2-utils',
    'ninja-build',
    'openssl',
    'protobuf-compiler',
    'unzip',
    'x11proto-core-dev',
    'xsltproc',
    'zip',
    'zlib1g-dev',
]

# List of cargo packages required for linux build
REQUIRED_CARGO_PACKAGES = ['cxxbridge-cmd']

APT_PKG_LIST = ['apt', '-qq', 'list']
CARGO_PKG_LIST = ['cargo', 'install', '--list']


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 bootstrap dir and make sure it exists
        self.bootstrap_dir = os.path.abspath(self.args.bootstrap_dir)
        os.makedirs(self.bootstrap_dir, exist_ok=True)

        # Output and platform directories are based on bootstrap
        self.output_dir = os.path.join(self.bootstrap_dir, 'output')
        self.platform_dir = os.path.join(self.bootstrap_dir, 'staging')
        self.sysroot = self.args.sysroot
        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')

    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 = not self.args.no_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/']

        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 not self.args.no_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)
        # Remove Cargo.lock that may have become generated
        os.remove(os.path.join(self.platform_dir, 'bt', 'Cargo.lock'))

    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()


class Bootstrap():

    def __init__(self, base_dir, bt_dir):
        """ Construct bootstrapper.

        Args:
            base_dir: Where to stage everything.
            bt_dir: Where bluetooth source is kept (will be symlinked)
        """
        self.base_dir = os.path.abspath(base_dir)
        self.bt_dir = os.path.abspath(bt_dir)

        # Create base directory if it doesn't already exist
        os.makedirs(self.base_dir, exist_ok=True)

        if not os.path.isdir(self.bt_dir):
            raise Exception('{} is not a valid directory'.format(self.bt_dir))

        self.git_dir = os.path.join(self.base_dir, 'repos')
        self.staging_dir = os.path.join(self.base_dir, 'staging')
        self.output_dir = os.path.join(self.base_dir, 'output')
        self.external_dir = os.path.join(self.base_dir, 'staging', 'external')

        self.dir_setup_complete = os.path.join(self.base_dir, '.setup-complete')

    def _update_platform2(self):
        """Updates repositories used for build."""
        for repo in BOOTSTRAP_GIT_REPOS.keys():
            cwd = os.path.join(self.git_dir, repo)
            subprocess.check_call(['git', 'pull'], cwd=cwd)

    def _setup_platform2(self):
        """ Set up platform2.

        This will check out all the git repos and symlink everything correctly.
        """

        # If already set up, exit early
        if os.path.isfile(self.dir_setup_complete):
            print('{} already set-up. Updating instead.'.format(self.base_dir))
            self._update_platform2()
            return

        # Create all directories we will need to use
        for dirpath in [self.git_dir, self.staging_dir, self.output_dir, self.external_dir]:
            os.makedirs(dirpath)

        # Check out all repos in git directory
        for repo in BOOTSTRAP_GIT_REPOS.values():
            subprocess.check_call(['git', 'clone', repo], cwd=self.git_dir)

        # Symlink things
        symlinks = [
            (os.path.join(self.git_dir, 'platform2', 'common-mk'), os.path.join(self.staging_dir, 'common-mk')),
            (os.path.join(self.git_dir, 'platform2', '.gn'), os.path.join(self.staging_dir, '.gn')),
            (os.path.join(self.bt_dir), os.path.join(self.staging_dir, 'bt')),
            (os.path.join(self.git_dir, 'rust_crates'), os.path.join(self.external_dir, 'rust')),
            (os.path.join(self.git_dir, 'proto_logging'), os.path.join(self.external_dir, 'proto_logging')),
        ]

        # Create symlinks
        for pairs in symlinks:
            (src, dst) = pairs
            os.symlink(src, dst)

        # Write to setup complete file so we don't repeat this step
        with open(self.dir_setup_complete, 'w') as f:
            f.write('Setup complete.')

    def _pretty_print_install(self, install_cmd, packages, line_limit=80):
        """ Pretty print an install command.

        Args:
            install_cmd: Prefixed install command.
            packages: Enumerate packages and append them to install command.
            line_limit: Number of characters per line.

        Return:
            Array of lines to join and print.
        """
        install = [install_cmd]
        line = '  '
        # Remainder needed = space + len(pkg) + space + \
        # Assuming 80 character lines, that's 80 - 3 = 77
        line_limit = line_limit - 3
        for pkg in packages:
            if len(line) + len(pkg) < line_limit:
                line = '{}{} '.format(line, pkg)
            else:
                install.append(line)
                line = '  {} '.format(pkg)

        if len(line) > 0:
            install.append(line)

        return install

    def _check_package_installed(self, package, cmd, predicate):
        """Check that the given package is installed.

        Args:
            package: Check that this package is installed.
            cmd: Command prefix to check if installed (package appended to end)
            predicate: Function/lambda to check if package is installed based
                       on output. Takes string output and returns boolean.

        Return:
            True if package is installed.
        """
        try:
            output = subprocess.check_output(cmd + [package], stderr=subprocess.STDOUT)
            is_installed = predicate(output.decode('utf-8'))
            print('  {} is {}'.format(package, 'installed' if is_installed else 'missing'))

            return is_installed
        except Exception as e:
            print(e)
            return False

    def _get_command_output(self, cmd):
        """Runs the command and gets the output.

        Args:
            cmd: Command to run.

        Return:
            Tuple (Success, Output). Success represents if the command ran ok.
        """
        try:
            output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
            return (True, output.decode('utf-8').split('\n'))
        except Exception as e:
            print(e)
            return (False, "")

    def _print_missing_packages(self):
        """Print any missing packages found via apt.

        This will find any missing packages necessary for build using apt and
        print it out as an apt-get install printf.
        """
        print('Checking for any missing packages...')

        (success, output) = self._get_command_output(APT_PKG_LIST)
        if not success:
            raise Exception("Could not query apt for packages.")

        packages_installed = {}
        for line in output:
            if 'installed' in line:
                split = line.split('/', 2)
                packages_installed[split[0]] = True

        need_packages = []
        for pkg in REQUIRED_APT_PACKAGES:
            if pkg not in packages_installed:
                need_packages.append(pkg)

        # No packages need to be installed
        if len(need_packages) == 0:
            print('+ All required packages are installed')
            return

        install = self._pretty_print_install('sudo apt-get install', need_packages)

        # Print all lines so they can be run in cmdline
        print('Missing system packages. Run the following command: ')
        print(' \\\n'.join(install))

    def _print_missing_rust_packages(self):
        """Print any missing packages found via cargo.

        This will find any missing packages necessary for build using cargo and
        print it out as a cargo-install printf.
        """
        print('Checking for any missing cargo packages...')

        (success, output) = self._get_command_output(CARGO_PKG_LIST)
        if not success:
            raise Exception("Could not query cargo for packages.")

        packages_installed = {}
        for line in output:
            # Cargo installed packages have this format
            # <crate name> <version>:
            #   <binary name>
            # We only care about the crates themselves
            if ':' not in line:
                continue

            split = line.split(' ', 2)
            packages_installed[split[0]] = True

        need_packages = []
        for pkg in REQUIRED_CARGO_PACKAGES:
            if pkg not in packages_installed:
                need_packages.append(pkg)

        # No packages to be installed
        if len(need_packages) == 0:
            print('+ All required cargo packages are installed')
            return

        install = self._pretty_print_install('cargo install', need_packages)
        print('Missing cargo packages. Run the following command: ')
        print(' \\\n'.join(install))

    def bootstrap(self):
        """ Bootstrap the Linux build."""
        self._setup_platform2()
        self._print_missing_packages()
        self._print_missing_rust_packages()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Simple build for host.')
    parser.add_argument(
        '--bootstrap-dir', help='Directory to run bootstrap on (or was previously run on).', default="~/.floss")
    parser.add_argument(
        '--run-bootstrap',
        help='Run bootstrap code to verify build env is ok to build.',
        default=False,
        action='store_true')
    parser.add_argument('--no-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/lib', default='usr/lib')
    parser.add_argument('--jobs', help='Number of jobs to run', default=0, type=int)
    parser.add_argument(
        '--no-vendored-rust', help='Do not use vendored rust crates', default=False, action='store_true')
    parser.add_argument('--verbose', help='Verbose logs for build.')
    args = parser.parse_args()

    # Make sure we get absolute path + expanded path for bootstrap directory
    args.bootstrap_dir = os.path.abspath(os.path.expanduser(args.bootstrap_dir))

    if args.run_bootstrap:
        bootstrap = Bootstrap(args.bootstrap_dir, os.path.dirname(__file__))
        bootstrap.bootstrap()
    else:
        build = HostBuild(args)
        build.build()
