#!/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 json
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',
      help='Where to store perf results in chartjson format.', default=None)

  # Ignore Chromium-specific flags
  parser.add_argument('--isolated-script-test-output',
                      type=str, default=None)
  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).
  """
  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*$'

    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, 'score')}
  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, 'score')}


def _AddChart(charts, metric, test_name, value, units):
  chart = charts.setdefault(metric, {})
  chart[test_name] = {
      "type": "scalar",
      "value": value,
      "units": units,
  }


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


def main():
  # pylint: disable=W0101
  logging.basicConfig(level=logging.INFO)

  args = _ParseArgs()

  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(_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(_RunPolqa, polqa_path, 48000))

  charts = {}

  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]),
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    try:
      lines = iter(test_process.stdout.readline, '')
      for result in ExtractTestRuns(lines, echo=True):
        (android_device, test_name, reference_file, degraded_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():
          # Output a result for the perf dashboard.
          print 'RESULT %s: %s= %s %s' % (metric, test_name, value, units)
          _AddChart(charts, metric, test_name, value, units)

        if args.remove:
          os.remove(reference_file)
          os.remove(degraded_file)
    finally:
      test_process.terminate()

  if args.isolated_script_test_perf_output:
    with open(args.isolated_script_test_perf_output, 'w') as f:
      json.dump({"format_version": "1.0", "charts": charts}, f)

  return test_process.wait()


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