#!/usr/bin/env vpython3

# Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.

"""MB - the Meta-Build wrapper around GN.

MB is a wrapper script for GN that can be used to generate build files
for sets of canned configurations and analyze them.
"""

import os
import sys

_SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
_SRC_DIR = os.path.dirname(os.path.dirname(_SCRIPT_DIR))
sys.path.insert(0, _SRC_DIR)

from tools.mb import mb


def _GetExecutable(target, platform):
  executable_prefix = '.\\' if platform == 'win32' else './'
  executable_suffix = '.exe' if platform == 'win32' else ''
  return executable_prefix + target + executable_suffix


def main(args):
  mbw = WebRTCMetaBuildWrapper()
  return mbw.Main(args)


class WebRTCMetaBuildWrapper(mb.MetaBuildWrapper):
  def __init__(self):
    super().__init__()
    # Make sure default_config and default_isolate_map are attributes of the
    # parent class before changing their values.
    # pylint: disable=access-member-before-definition
    assert self.default_config
    assert self.default_isolate_map
    self.default_config = os.path.join(_SCRIPT_DIR, 'mb_config.pyl')
    self.default_isolate_map = os.path.join(_SRC_DIR, 'infra', 'specs',
                                            'gn_isolate_map.pyl')

  def GetSwarmingCommand(self, target, vals):
    isolate_map = self.ReadIsolateMap()
    test_type = isolate_map[target]['type']

    is_android = 'target_os="android"' in vals['gn_args']
    is_fuchsia = 'target_os="fuchsia"' in vals['gn_args']
    is_linux = self.platform.startswith('linux') and not is_android
    is_ios = 'target_os="ios"' in vals['gn_args']

    if test_type == 'nontest':
      self.WriteFailureAndRaise('We should not be isolating %s.' % target,
                                output_path=None)
    if test_type not in ('console_test_launcher', 'windowed_test_launcher',
                         'non_parallel_console_test_launcher', 'raw',
                         'additional_compile_target', 'junit_test', 'script'):
      self.WriteFailureAndRaise('No command line for '
                                '%s found (test type %s).' %
                                (target, test_type),
                                output_path=None)

    cmdline = []
    extra_files = [
        '../../.vpython3',
        '../../testing/test_env.py',
    ]
    vpython_exe = 'vpython3'

    if isolate_map[target].get('script'):
      cmdline += [
          vpython_exe,
          '../../' + self.ToSrcRelPath(isolate_map[target]['script'])
      ]
    elif is_android:
      cmdline += [
          vpython_exe, '../../build/android/test_wrapper/logdog_wrapper.py',
          '--target', target, '--logdog-bin-cmd', '../../bin/logdog_butler',
          '--logcat-output-file', '${ISOLATED_OUTDIR}/logcats',
          '--store-tombstones'
      ]
    elif is_ios or is_fuchsia:
      cmdline += [
          vpython_exe, '../../tools_webrtc/flags_compatibility.py',
          'bin/run_%s' % target
      ]
      extra_files.append('../../tools_webrtc/flags_compatibility.py')
    elif test_type == 'raw':
      cmdline += [vpython_exe, '../../tools_webrtc/flags_compatibility.py']
      extra_files.append('../../tools_webrtc/flags_compatibility.py')
      cmdline.append(_GetExecutable(target, self.platform))
    else:
      if isolate_map[target].get('use_webcam', False):
        cmdline += [
            vpython_exe, '../../tools_webrtc/ensure_webcam_is_running.py'
        ]
        extra_files.append('../../tools_webrtc/ensure_webcam_is_running.py')
      if isolate_map[target].get('use_pipewire', False):
        cmdline += [vpython_exe, '../../tools_webrtc/configure_pipewire.py']
        extra_files.append('../../tools_webrtc/configure_pipewire.py')

      # is_linux uses use_ozone and x11 by default.
      use_x11 = is_linux

      xvfb = use_x11 and test_type == 'windowed_test_launcher'
      if xvfb:
        cmdline += [vpython_exe, '../../testing/xvfb.py']
        extra_files.append('../../testing/xvfb.py')
      else:
        cmdline += [vpython_exe, '../../testing/test_env.py']

      extra_files += [
          '../../third_party/gtest-parallel/gtest-parallel',
          '../../third_party/gtest-parallel/gtest_parallel.py',
          '../../tools_webrtc/gtest-parallel-wrapper.py',
      ]
      output_dir = '${ISOLATED_OUTDIR}/test_logs'
      timeout = isolate_map[target].get('timeout', 900)
      cmdline += [
          '../../tools_webrtc/gtest-parallel-wrapper.py',
          '--output_dir=%s' % output_dir,
          '--gtest_color=no',
          # We tell gtest-parallel to interrupt the test after 900
          # seconds, so it can exit cleanly and report results,
          # instead of being interrupted by swarming and not
          # reporting anything.
          '--timeout=%s' % timeout,
      ]
      if test_type == 'non_parallel_console_test_launcher':
        # Still use the gtest-parallel-wrapper.py script since we
        # need it to run tests on swarming, but don't execute tests
        # in parallel.
        cmdline.append('--workers=1')

      asan = 'is_asan=true' in vals['gn_args']
      lsan = 'is_lsan=true' in vals['gn_args']
      msan = 'is_msan=true' in vals['gn_args']
      tsan = 'is_tsan=true' in vals['gn_args']
      sanitizer = asan or lsan or msan or tsan
      if not sanitizer:
        # Retry would hide most sanitizers detections.
        cmdline.append('--retry_failed=3')

      cmdline.append(_GetExecutable(target, self.platform))

      cmdline.extend([
          '--asan=%d' % asan,
          '--lsan=%d' % lsan,
          '--msan=%d' % msan,
          '--tsan=%d' % tsan,
      ])

    cmdline += isolate_map[target].get('args', [])

    return cmdline, extra_files

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