#!/usr/bin/env python3
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Builds crosvm in debug/release mode on all supported target architectures.

A sysroot for each target architectures is required. The defaults are all
generic boards' sysroots, but they can be changed with the command line
arguments.

To test changes more quickly, set the --noclean option. This prevents the
target directories from being removed before building and testing.
"""

from __future__ import print_function
import argparse
import multiprocessing.pool
import os
import shutil
import subprocess
import sys

ARM_TRIPLE = os.getenv('ARM_TRIPLE', 'armv7a-cros-linux-gnueabihf')
AARCH64_TRIPLE = os.getenv('AARCH64_TRIPLE', 'aarch64-cros-linux-gnu')
X86_64_TRIPLE = os.getenv('X86_64_TRIPLE', 'x86_64-cros-linux-gnu')

TEST_MODULES_PARALLEL = [
    'arch',
    'assertions',
    'bit_field',
    'crosvm',
    'data_model',
    'devices',
    'disk',
    'enumn',
    'hypervisor',
    'kernel_cmdline',
    'kernel_loader',
    'kvm',
    'kvm_sys',
    'msg_socket',
    'net_sys',
    'net_util',
    'qcow_utils',
    'rand_ish',
    'resources',
    'sync',
    'syscall_defines',
    'tpm2',
    'vhost',
    'virtio_sys',
    'vm_control',
    'x86_64',
]

TEST_MODULES_SERIAL = [
    'sys_util',
    'base',
]

# Bright green.
PASS_COLOR = '\033[1;32m'
# Bright red.
FAIL_COLOR = '\033[1;31m'
# Default color.
END_COLOR = '\033[0m'


def get_target_path(triple, kind, test_it):
  """Constructs a target path based on the configuration parameters.

  Args:
    triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
    kind: 'debug' or 'release'.
    test_it: If this target is tested.
  """
  target_path = '/tmp/%s_%s' % (triple, kind)
  if test_it:
    target_path += '_test'
  return target_path


def build_target(triple, is_release, env):
  """Does a cargo build for the triple in release or debug mode.

  Args:
    triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
    is_release: True to build a release version.
    env: Enviroment variables to run cargo with.
  """
  args = ['cargo', 'build', '--target=%s' % triple]

  if is_release:
    args.append('--release')

  return subprocess.Popen(args, env=env).wait() == 0


def test_target_modules(triple, is_release, env, modules, parallel):
  """Does a cargo test on given modules for the triple and configuration.

  Args:
    triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
    is_release: True to build a release version.
    env: Enviroment variables to run cargo with.
    modules: List of module strings to test.
    parallel: True to run the tests in parallel threads.
  """
  args = ['cargo', 'test', '--target=%s' % triple]

  if is_release:
    args.append('--release')

  for mod in modules:
    args.append('-p')
    args.append(mod)

  if not parallel:
    args.append('--')
    args.append('--test-threads=1')

  return subprocess.Popen(args, env=env).wait() == 0


def test_target(triple, is_release, env):
  """Does a cargo test for the given triple and configuration.

  Args:
    triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
    is_release: True to build a release version.
    env: Enviroment variables to run cargo with.
  """

  parallel_result = test_target_modules(
      triple, is_release, env, TEST_MODULES_PARALLEL, True)

  serial_result = test_target_modules(
      triple, is_release, env, TEST_MODULES_SERIAL, False)

  return parallel_result and serial_result


def check_build(sysroot, triple, kind, test_it, clean):
  """Runs relavent builds/tests for the given triple and configuration

  Args:
    sysroot: path to the target's sysroot directory.
    triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
    kind: 'debug' or 'release'.
    test_it: True to test this triple and kind.
    clean: True to skip cleaning the target path.
  """
  if not os.path.isdir(sysroot):
    return 'sysroot missing'

  target_path = get_target_path(triple, kind, test_it)

  if clean:
    shutil.rmtree(target_path, True)

  is_release = kind == 'release'

  # The pkgconfig dir could be in either lib or lib64 depending on the target.
  # Rather than checking to see which one is valid, just add both and let
  # pkg-config search.
  libdir = os.path.join(sysroot, 'usr', 'lib', 'pkgconfig')
  lib64dir = os.path.join(sysroot, 'usr', 'lib64', 'pkgconfig')

  env = os.environ.copy()
  env['TARGET_CC'] = '%s-clang'%triple
  env['SYSROOT'] = sysroot
  env['CARGO_TARGET_DIR'] = target_path
  env['PKG_CONFIG_ALLOW_CROSS'] = '1'
  env['PKG_CONFIG_LIBDIR'] = libdir + ':' + lib64dir
  env['PKG_CONFIG_SYSROOT_DIR'] = sysroot
  env['RUSTFLAGS'] = '-C linker=' + env['TARGET_CC']

  if test_it:
    if not test_target(triple, is_release, env):
      return 'test error'
  else:
    if not build_target(triple, is_release, env):
      return 'build error'

  return 'pass'


def get_stripped_size(triple):
  """Returns the formatted size of the given triple's release binary.

  Args:
    triple: Target triple. Example: 'x86_64-unknown-linux-gnu'.
  """
  target_path = get_target_path(triple, 'release', False)
  bin_path = os.path.join(target_path, triple, 'release', 'crosvm')
  proc = subprocess.Popen(['%s-strip' % triple, bin_path])

  if proc.wait() != 0:
    return 'failed'

  return '%dKiB' % (os.path.getsize(bin_path) / 1024)


def get_parser():
  """Gets the argument parser"""
  parser = argparse.ArgumentParser(description=__doc__)
  parser.add_argument('--arm-sysroot',
                      default='/build/arm-generic',
                      help='ARM sysroot directory (default=%(default)s)')
  parser.add_argument('--aarch64-sysroot',
                      default='/build/arm64-generic',
                      help='AARCH64 sysroot directory (default=%(default)s)')
  parser.add_argument('--x86_64-sysroot',
                      default='/build/amd64-generic',
                      help='x86_64 sysroot directory (default=%(default)s)')
  parser.add_argument('--noclean', dest='clean', default=True,
                      action='store_false',
                      help='Keep the tempororary build directories.')
  return parser


def main(argv):
  opts = get_parser().parse_args(argv)
  build_test_cases = (
      #(sysroot path, target triple, debug/release, should test?)
      (opts.arm_sysroot, ARM_TRIPLE, "debug", False, opts.clean),
      (opts.arm_sysroot, ARM_TRIPLE, "release", False, opts.clean),
      (opts.aarch64_sysroot, AARCH64_TRIPLE, "debug", False, opts.clean),
      (opts.aarch64_sysroot, AARCH64_TRIPLE, "release", False, opts.clean),
      (opts.x86_64_sysroot, X86_64_TRIPLE, "debug", False, opts.clean),
      (opts.x86_64_sysroot, X86_64_TRIPLE, "release", False, opts.clean),
      (opts.x86_64_sysroot, X86_64_TRIPLE, "debug", True, opts.clean),
      (opts.x86_64_sysroot, X86_64_TRIPLE, "release", True, opts.clean),
  )

  os.chdir(os.path.dirname(sys.argv[0]))
  pool = multiprocessing.pool.Pool(len(build_test_cases))
  results = pool.starmap(check_build, build_test_cases, 1)

  print('---')
  print('build test summary:')
  for test_case, result in zip(build_test_cases, results):
    _, triple, kind, test_it, _ = test_case
    title = '%s_%s' % (triple.split('-')[0], kind)
    if test_it:
      title += "_test"

    result_color = FAIL_COLOR
    if result == 'pass':
      result_color = PASS_COLOR

    display_size = ''
    if result == 'pass' and kind == 'release' and not test_it:
      display_size = get_stripped_size(triple) + ' stripped binary'

    print('%20s: %s%15s%s %s' %
          (title, result_color, result, END_COLOR, display_size))


if __name__ == '__main__':
  sys.exit(main(sys.argv[1:]))
