#!/usr/bin/env python
# Copyright (c) 2017 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.

"""
This script is the wrapper that runs the low-bandwidth audio test.

After running the test, post-process steps for calculating audio quality of the
output files will be performed.
"""

import argparse
import collections
import logging
import os
import re
import shutil
import subprocess
import sys


SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
SRC_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, os.pardir, os.pardir))

NO_TOOLS_ERROR_MESSAGE = (
  'Could not find PESQ or POLQA at %s.\n'
  '\n'
  'To fix this run:\n'
  '  python %s %s\n'
  '\n'
  'Note that these tools are Google-internal due to licensing, so in order to '
  'use them you will have to get your own license and manually put them in the '
  'right location.\n'
  'See https://cs.chromium.org/chromium/src/third_party/webrtc/tools_webrtc/'
  'download_tools.py?rcl=bbceb76f540159e2dba0701ac03c514f01624130&l=13')


def _LogCommand(command):
  logging.info('Running %r', command)
  return command


def _ParseArgs():
  parser = argparse.ArgumentParser(description='Run low-bandwidth audio tests.')
  parser.add_argument('build_dir',
      help='Path to the build directory (e.g. out/Release).')
  parser.add_argument('--remove', action='store_true',
      help='Remove output audio files after testing.')
  parser.add_argument('--android', action='store_true',
      help='Perform the test on a connected Android device instead.')
  parser.add_argument('--adb-path', help='Path to adb binary.', default='adb')
  parser.add_argument('--num-retries', default='0',
                      help='Number of times to retry the test on Android.')
  parser.add_argument('--isolated_script_test_perf_output', default=None,
      help='Path to store perf results in histogram proto format.')
  parser.add_argument('--extra-test-args', default=[], action='append',
      help='Extra args to path to the test binary.')

  # Ignore Chromium-specific flags
  parser.add_argument('--test-launcher-summary-output',
                      type=str, default=None)
  args = parser.parse_args()

  return args


def _GetPlatform():
  if sys.platform == 'win32':
    return 'win'
  elif sys.platform == 'darwin':
    return 'mac'
  elif sys.platform.startswith('linux'):
    return 'linux'


def _GetExtension():
  return '.exe' if sys.platform == 'win32' else ''


def _GetPathToTools():
  tools_dir = os.path.join(SRC_DIR, 'tools_webrtc')
  toolchain_dir = os.path.join(tools_dir, 'audio_quality')

  platform = _GetPlatform()
  ext = _GetExtension()

  pesq_path = os.path.join(toolchain_dir, platform, 'pesq' + ext)
  if not os.path.isfile(pesq_path):
    pesq_path = None

  polqa_path = os.path.join(toolchain_dir, platform, 'PolqaOem64' + ext)
  if not os.path.isfile(polqa_path):
    polqa_path = None

  if (platform != 'mac' and not polqa_path) or not pesq_path:
    logging.error(NO_TOOLS_ERROR_MESSAGE,
                  toolchain_dir,
                  os.path.join(tools_dir, 'download_tools.py'),
                  toolchain_dir)

  return pesq_path, polqa_path


def ExtractTestRuns(lines, echo=False):
  """Extracts information about tests from the output of a test runner.

  Produces tuples
  (android_device, test_name, reference_file, degraded_file, cur_perf_results).
  """
  for line in lines:
    if echo:
      sys.stdout.write(line)

    # Output from Android has a prefix with the device name.
    android_prefix_re = r'(?:I\b.+\brun_tests_on_device\((.+?)\)\s*)?'
    test_re = r'^' + android_prefix_re + (r'TEST (\w+) ([^ ]+?) ([^\s]+)'
                                          r' ?([^\s]+)?\s*$')

    match = re.search(test_re, line)
    if match:
      yield match.groups()


def _GetFile(file_path, out_dir, move=False,
             android=False, adb_prefix=('adb',)):
  out_file_name = os.path.basename(file_path)
  out_file_path = os.path.join(out_dir, out_file_name)

  if android:
    # Pull the file from the connected Android device.
    adb_command = adb_prefix + ('pull', file_path, out_dir)
    subprocess.check_call(_LogCommand(adb_command))
    if move:
      # Remove that file.
      adb_command = adb_prefix + ('shell', 'rm', file_path)
      subprocess.check_call(_LogCommand(adb_command))
  elif os.path.abspath(file_path) != os.path.abspath(out_file_path):
    if move:
      shutil.move(file_path, out_file_path)
    else:
      shutil.copy(file_path, out_file_path)

  return out_file_path


def _RunPesq(executable_path, reference_file, degraded_file,
             sample_rate_hz=16000):
  directory = os.path.dirname(reference_file)
  assert os.path.dirname(degraded_file) == directory

  # Analyze audio.
  command = [executable_path, '+%d' % sample_rate_hz,
             os.path.basename(reference_file),
             os.path.basename(degraded_file)]
  # Need to provide paths in the current directory due to a bug in PESQ:
  # On Mac, for some 'path/to/file.wav', if 'file.wav' is longer than
  # 'path/to', PESQ crashes.
  out = subprocess.check_output(_LogCommand(command),
                                cwd=directory, stderr=subprocess.STDOUT)

  # Find the scores in stdout of PESQ.
  match = re.search(
      r'Prediction \(Raw MOS, MOS-LQO\):\s+=\s+([\d.]+)\s+([\d.]+)', out)
  if match:
    raw_mos, _ = match.groups()

    return {'pesq_mos': (raw_mos, 'unitless')}
  else:
    logging.error('PESQ: %s', out.splitlines()[-1])
    return {}


def _RunPolqa(executable_path, reference_file, degraded_file):
  # Analyze audio.
  command = [executable_path, '-q', '-LC', 'NB',
             '-Ref', reference_file, '-Test', degraded_file]
  process = subprocess.Popen(_LogCommand(command),
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  out, err = process.communicate()

  # Find the scores in stdout of POLQA.
  match = re.search(r'\bMOS-LQO:\s+([\d.]+)', out)

  if process.returncode != 0 or not match:
    if process.returncode == 2:
      logging.warning('%s (2)', err.strip())
      logging.warning('POLQA license error, skipping test.')
    else:
      logging.error('%s (%d)', err.strip(), process.returncode)
    return {}

  mos_lqo, = match.groups()
  return {'polqa_mos_lqo': (mos_lqo, 'unitless')}


def _MergeInPerfResultsFromCcTests(histograms, run_perf_results_file):
  from tracing.value import histogram_set

  cc_histograms = histogram_set.HistogramSet()
  with open(run_perf_results_file, 'rb') as f:
    contents = f.read()
    if not contents:
      return

    cc_histograms.ImportProto(contents)

  histograms.Merge(cc_histograms)


Analyzer = collections.namedtuple('Analyzer', ['name', 'func', 'executable',
                                               'sample_rate_hz'])


def _ConfigurePythonPath(args):
  script_dir = os.path.dirname(os.path.realpath(__file__))
  checkout_root = os.path.abspath(
      os.path.join(script_dir, os.pardir, os.pardir))

  sys.path.insert(0, os.path.join(checkout_root, 'third_party', 'catapult',
                                  'tracing'))
  sys.path.insert(0, os.path.join(checkout_root, 'third_party', 'protobuf',
                                  'python'))

  # The low_bandwidth_audio_perf_test gn rule will build the protobuf stub for
  # python, so put it in the path for this script before we attempt to import
  # it.
  histogram_proto_path = os.path.join(
      args.build_dir, 'pyproto', 'tracing', 'tracing', 'proto')
  sys.path.insert(0, histogram_proto_path)

  logging.info('Contents of build dir:')
  logging.info(str(os.listdir(args.build_dir)))
  for root, dirs, files in os.walk(os.path.join(args.build_dir, 'pyproto')):
    path = root.split(os.sep)
    logging.info((len(path) - 1) * '---' + os.path.basename(root))
    for file in files:
        logging.info(len(path) * '---' + file)

  # Fail early in case the proto hasn't been built.
  from tracing.proto import histogram_proto
  if not histogram_proto.HAS_PROTO:
    raise ImportError('Could not find histogram_pb2. You need to build the '
                      'low_bandwidth_audio_perf_test target before invoking '
                      'this script. Expected to find '
                      'histogram_pb2.py in %s.' % histogram_proto_path)


def main():
  # pylint: disable=W0101
  logging.basicConfig(level=logging.INFO)
  logging.info('Invoked with %s', str(sys.argv))

  args = _ParseArgs()

  _ConfigurePythonPath(args)

  # Import catapult modules here after configuring the pythonpath.
  from tracing.value import histogram_set
  from tracing.value.diagnostics import reserved_infos
  from tracing.value.diagnostics import generic_set

  pesq_path, polqa_path = _GetPathToTools()
  if pesq_path is None:
    return 1

  out_dir = os.path.join(args.build_dir, '..')
  if args.android:
    test_command = [os.path.join(args.build_dir, 'bin',
                                 'run_low_bandwidth_audio_test'),
                    '-v', '--num-retries', args.num_retries]
  else:
    test_command = [os.path.join(args.build_dir, 'low_bandwidth_audio_test')]

  analyzers = [Analyzer('pesq', _RunPesq, pesq_path, 16000)]
  # Check if POLQA can run at all, or skip the 48 kHz tests entirely.
  example_path = os.path.join(SRC_DIR, 'resources',
                              'voice_engine', 'audio_tiny48.wav')
  if polqa_path and _RunPolqa(polqa_path, example_path, example_path):
    analyzers.append(Analyzer('polqa', _RunPolqa, polqa_path, 48000))

  histograms = histogram_set.HistogramSet()
  for analyzer in analyzers:
    # Start the test executable that produces audio files.
    test_process = subprocess.Popen(
        _LogCommand(test_command + [
            '--sample_rate_hz=%d' % analyzer.sample_rate_hz,
            '--test_case_prefix=%s' % analyzer.name,
            '--write_histogram_proto_json'
          ] + args.extra_test_args),
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    perf_results_file = None
    try:
      lines = iter(test_process.stdout.readline, '')
      for result in ExtractTestRuns(lines, echo=True):
        (android_device, test_name, reference_file, degraded_file,
         perf_results_file) = result

        adb_prefix = (args.adb_path,)
        if android_device:
          adb_prefix += ('-s', android_device)

        reference_file = _GetFile(reference_file, out_dir,
                                  android=args.android, adb_prefix=adb_prefix)
        degraded_file = _GetFile(degraded_file, out_dir, move=True,
                                 android=args.android, adb_prefix=adb_prefix)

        analyzer_results = analyzer.func(analyzer.executable,
                                         reference_file, degraded_file)
        for metric, (value, units) in analyzer_results.items():
          hist = histograms.CreateHistogram(metric, units, [value])
          user_story = generic_set.GenericSet([test_name])
          hist.diagnostics[reserved_infos.STORIES.name] = user_story

          # Output human readable results.
          print 'RESULT %s: %s= %s %s' % (metric, test_name, value, units)

        if args.remove:
          os.remove(reference_file)
          os.remove(degraded_file)
    finally:
      test_process.terminate()
    if perf_results_file:
      perf_results_file = _GetFile(perf_results_file, out_dir, move=True,
                           android=args.android, adb_prefix=adb_prefix)
      _MergeInPerfResultsFromCcTests(histograms, perf_results_file)
      if args.remove:
        os.remove(perf_results_file)

  if args.isolated_script_test_perf_output:
    with open(args.isolated_script_test_perf_output, 'wb') as f:
      f.write(histograms.AsProto().SerializeToString())

  return test_process.wait()


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