#!/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.

import glob
import optparse
import os
import shutil
import subprocess
import sys
import time


# Used to time-stamp output files and directories
CURRENT_TIME = time.strftime("%d_%m_%Y-%H:%M:%S")


class Error(Exception):
  pass


class FfmpegError(Error):
  pass


class MagewellError(Error):
  pass


class CompareVideosError(Error):
  pass


def _ParseArgs():
  """Registers the command-line options."""
  usage = 'usage: %prog [options]'
  parser = optparse.OptionParser(usage=usage)

  parser.add_option('--frame_width', type='int', default=1280,
                    help='Width of the recording. Default: %default')
  parser.add_option('--frame_height', type='int', default=720,
                    help='Height of the recording. Default: %default')
  parser.add_option('--framerate', type='int', default=60,
                    help='Recording framerate. Default: %default')
  parser.add_option('--ref_duration', type='int', default=20,
                    help='Reference recording duration. Default: %default')
  parser.add_option('--test_duration', type='int', default=10,
                    help='Test recording duration. Default: %default')
  parser.add_option('--time_between_recordings', type='int', default=5,
                    help='Time between starting test recording after ref.'
                    'Default: %default')
  parser.add_option('--ref_video_device', type='string', default='/dev/video0',
                    help='Reference recording device. Default: %default')
  parser.add_option('--test_video_device', type='string', default='/dev/video1',
                    help='Test recording device. Default: %default')
  parser.add_option('--app_name', type='string',
                    help='Name of the app under test.')
  parser.add_option('--recording_api', type='string', default='Video4Linux2',
                    help='Recording API to use. Default: %default')
  parser.add_option('--pixel_format', type='string', default='yuv420p',
                    help='Recording pixel format Default: %default')
  parser.add_option('--ffmpeg', type='string',
                    help='Path to the ffmpeg executable for the reference '
                    'device.')
  parser.add_option('--video_container', type='string', default='yuv',
                    help='Video container for the recordings.'
                    'Default: %default')
  parser.add_option('--compare_videos_script', type='string',
                    default='compare_videos.py',
                    help='Path to script used to compare and generate metrics.'
                    'Default: %default')
  parser.add_option('--frame_analyzer', type='string',
                    default='../../out/Default/frame_analyzer',
                    help='Path to the frame analyzer executable.'
                    'Default: %default')
  parser.add_option('--zxing_path', type='string',
                    help='Path to the zebra xing barcode analyzer.')
  parser.add_option('--ref_rec_dir', type='string', default='ref',
                    help='Path to where reference recordings will be created.'
                    'Ideally keep the ref and test directories on separate'
                    'drives. Default: %default')
  parser.add_option('--test_rec_dir', type='string', default='test',
                    help='Path to where test recordings will be created.'
                    'Ideally keep the ref and test directories on separate '
                    'drives. Default: %default')
  parser.add_option('--test_crop_parameters', type='string',
                    help='ffmpeg processing parameters for the test video.')
  parser.add_option('--ref_crop_parameters', type='string',
                    help='ffmpeg processing parameters for the ref video.')

  options, _ = parser.parse_args()

  if not options.app_name:
    parser.error('You must provide an application name!')

  if not options.test_crop_parameters or not options.ref_crop_parameters:
    parser.error('You must provide ref and test crop parameters!')

  # Ensure the crop filter is included in the crop parameters used for ffmpeg.
  if 'crop' not in options.ref_crop_parameters:
    parser.error('You must provide a reference crop filter for ffmpeg.')
  if 'crop' not in options.test_crop_parameters:
    parser.error('You must provide a test crop filter for ffmpeg.')

  if not options.ffmpeg:
    parser.error('You most provide location for the ffmpeg executable.')
  if not os.path.isfile(options.ffmpeg):
    parser.error('Cannot find the ffmpeg executable.')

  # compare_videos.py dependencies.
  if not os.path.isfile(options.compare_videos_script):
    parser.warning('Cannot find compare_videos.py script, no metrics will be '
                   'generated!')
  if not os.path.isfile(options.frame_analyzer):
    parser.warning('Cannot find frame_analyzer, no metrics will be generated!')
  if not os.path.isfile(options.zxing_path):
    parser.warning('Cannot find Zebra Xing, no metrics will be generated!')

  return options


def CreateRecordingDirs(options):
  """Create root + sub directories for reference and test recordings.

  Args:
    options(object): Contains all the provided command line options.

  Returns:
    record_paths(dict): key: value pair with reference and test file
        absolute paths.
  """

  # Create root directories for the video recordings.
  if not os.path.isdir(options.ref_rec_dir):
    os.makedirs(options.ref_rec_dir)
  if not os.path.isdir(options.test_rec_dir):
    os.makedirs(options.test_rec_dir)

  # Create and time-stamp directories for all the output files.
  ref_rec_dir = os.path.join(options.ref_rec_dir, options.app_name + '_' + \
    CURRENT_TIME)
  test_rec_dir = os.path.join(options.test_rec_dir, options.app_name + '_' + \
    CURRENT_TIME)

  os.makedirs(ref_rec_dir)
  os.makedirs(test_rec_dir)

  record_paths = {
    'ref_rec_location' : os.path.abspath(ref_rec_dir),
    'test_rec_location' : os.path.abspath(test_rec_dir)
  }

  return record_paths


def FindUsbPortForV4lDevices(ref_video_device, test_video_device):
  """Tries to find the usb port for ref_video_device and test_video_device.

  Tries to find the provided ref_video_device and test_video_device devices
  which use video4linux and then do a soft reset by using USB unbind and bind.

  Args:
    ref_device(string): reference recording device path.
    test_device(string): test recording device path

  Returns:
    usb_ports(list): USB ports(string) for the devices found.
  """

  # Find the device location including USB and USB Bus ID's. Use the usb1
  # in the path since the driver folder is a symlink which contains all the
  # usb device port mappings and it's the same in all usbN folders. Tested
  # on Ubuntu 14.04.
  v4l_device_path = '/sys/bus/usb/devices/usb1/1-1/driver/**/**/video4linux/'
  v4l_ref_device = glob.glob('%s%s' % (v4l_device_path, ref_video_device))
  v4l_test_device = glob.glob('%s%s' % (v4l_device_path, test_video_device))
  usb_ports = []
  paths = []

  # Split on the driver folder first since we are only interested in the
  # folders thereafter.
  try:
    ref_path = str(v4l_ref_device).split('driver')[1].split('/')
    test_path = str(v4l_test_device).split('driver')[1].split('/')
  except IndexError:
    print 'Could not find one or both of the specified recording devices.'
  else:
    paths.append(ref_path)
    paths.append(test_path)

    for path in paths:
      for usb_id in path:
        # Look for : separator and then use the first element in the list.
        # E.g 3-3.1:1.0 split on : and [0] becomes 3-3.1 which can be used
        # for bind/unbind.
        if ':' in usb_id:
          usb_ports.append(usb_id.split(':')[0])

  return usb_ports


def RestartMagewellDevices(ref_video_device_path, test_video_device_path):
  """Reset the USB ports where Magewell capture devices are connected to.

  Performs a soft reset by using USB unbind and bind.
  This is due to Magewell capture devices have proven to be unstable after the
  first recording attempt.

  Args:
    ref_video_device_path(string): reference recording device path.
    test_video_device_path(string): test recording device path

  Raises:
    MagewellError: If no magewell devices are found.
  """

  # Get the dev/videoN device name from the command line arguments.
  ref_magewell_path = ref_video_device_path.split('/')[2]
  test_magewell_path = test_video_device_path.split('/')[2]
  magewell_usb_ports = FindUsbPortForV4lDevices(ref_magewell_path,
                                                test_magewell_path)

  # Abort early if no devices are found.
  if len(magewell_usb_ports) == 0:
    raise MagewellError('No magewell devices found.')
  else:
    print '\nResetting USB ports where magewell devices are connected...'
    # Use the USB bus and port ID (e.g. 4-3) to unbind and bind the USB devices
    # (i.e. soft eject and insert).
    for usb_port in magewell_usb_ports:
      echo_cmd = ['echo', usb_port]
      unbind_cmd = ['sudo', 'tee', '/sys/bus/usb/drivers/usb/unbind']
      bind_cmd = ['sudo', 'tee', '/sys/bus/usb/drivers/usb/bind']

      # TODO(jansson) Figure out a way to call on echo once for bind & unbind
      # if possible.
      echo_unbind = subprocess.Popen(echo_cmd, stdout=subprocess.PIPE)
      unbind = subprocess.Popen(unbind_cmd, stdin=echo_unbind.stdout)
      echo_unbind.stdout.close()
      unbind.wait()

      echo_bind = subprocess.Popen(echo_cmd, stdout=subprocess.PIPE)
      bind = subprocess.Popen(bind_cmd, stdin=echo_bind.stdout)
      echo_bind.stdout.close()
      bind.wait()
  if bind.returncode == 0:
    print 'Reset done!\n'


def StartRecording(options, ref_file_location, test_file_location):
  """Starts recording from the two specified video devices.

  Args:
    options(object): Contains all the provided command line options.
    record_paths(dict): key: value pair with reference and test file
        absolute paths.

  Returns:
    recording_files_and_time(dict): key: value pair with the path to cropped
        test and reference video files.

  Raises:
    FfmpegError: If the ffmpeg command fails.
  """
  ref_file_name = '%s_%s_ref.%s' % (options.app_name, CURRENT_TIME,
    options.video_container)
  ref_file = os.path.join(ref_file_location, ref_file_name)

  test_file_name = '%s_%s_test.%s' % (options.app_name, CURRENT_TIME,
    options.video_container)
  test_file = os.path.join(test_file_location, test_file_name)

  # Reference video recorder command line.
  ref_cmd = [
    options.ffmpeg,
    '-v', 'error',
    '-s', '%dx%d' % (options.frame_width, options.frame_height),
    '-r', '%d' % options.framerate,
    '-f', '%s' % options.recording_api,
    '-i', '%s' % options.ref_video_device,
    '-pix_fmt', '%s' % options.pixel_format,
    '-s', '%dx%d' % (options.frame_width, options.frame_height),
    '-t', '%d' % options.ref_duration,
    '-r', '%d' % options.framerate,
    ref_file
  ]

  # Test video recorder command line.
  test_cmd = [
    options.ffmpeg,
    '-v', 'error',
    '-s', '%dx%d' % (options.frame_width, options.frame_height),
    '-r', '%d' % options.framerate,
    '-f', '%s' % options.recording_api,
    '-i', '%s' % options.test_video_device,
    '-pix_fmt', '%s' % options.pixel_format,
    '-s', '%dx%d' % (options.frame_width, options.frame_height),
    '-t', '%d' % options.test_duration,
    '-r', '%d' % options.framerate,
    test_file
  ]
  print 'Trying to record from reference recorder...'
  ref_recorder = subprocess.Popen(ref_cmd)

  # Start the 2nd recording a little later to ensure the 1st one has started.
  # TODO(jansson) Check that the ref_recorder output file exists rather than
  # using sleep.
  time.sleep(options.time_between_recordings)
  print 'Trying to record from test recorder...'
  test_recorder = subprocess.Popen(test_cmd)
  test_recorder.wait()
  ref_recorder.wait()

  # ffmpeg does not abort when it fails, need to check return code.
  if ref_recorder.returncode != 0 or test_recorder.returncode != 0:
    # Cleanup recording directories.
    shutil.rmtree(ref_file_location)
    shutil.rmtree(test_file_location)
    raise FfmpegError('Recording failed, check ffmpeg output.')
  else:
    print 'Ref file recorded to: ' + os.path.abspath(ref_file)
    print 'Test file recorded to: ' + os.path.abspath(test_file)
    print 'Recording done!\n'
    return FlipAndCropRecordings(options, test_file_name, test_file_location,
        ref_file_name, ref_file_location)


def FlipAndCropRecordings(options, test_file_name, test_file_location,
                          ref_file_name, ref_file_location):
  """Performs a horizontal flip of the reference video to match the test video.

  This is done to the match orientation and then crops the ref and test videos
  using the options.test_crop_parameters and options.ref_crop_parameters.

  Args:
    options(object): Contains all the provided command line options.
    test_file_name(string): Name of the test video file recording.
    test_file_location(string): Path to the test video file recording.
    ref_file_name(string): Name of the reference video file recording.
    ref_file_location(string): Path to the reference video file recording.

  Returns:
    recording_files_and_time(dict): key: value pair with the path to cropped
        test and reference video files.

  Raises:
    FfmpegError: If the ffmpeg command fails.
  """
  print 'Trying to crop videos...'

  # Ref file cropping.
  cropped_ref_file_name = 'cropped_' + ref_file_name
  cropped_ref_file = os.path.abspath(
      os.path.join(ref_file_location, cropped_ref_file_name))

  ref_video_crop_cmd = [
    options.ffmpeg,
    '-v', 'error',
    '-s', '%dx%d' % (options.frame_width, options.frame_height),
    '-i', '%s' % os.path.join(ref_file_location, ref_file_name),
    '-vf', '%s' % options.ref_crop_parameters,
    '-c:a', 'copy',
    cropped_ref_file
  ]

  # Test file cropping.
  cropped_test_file_name = 'cropped_' + test_file_name
  cropped_test_file = os.path.abspath(
      os.path.join(test_file_location, cropped_test_file_name))

  test_video_crop_cmd = [
    options.ffmpeg,
    '-v', 'error',
    '-s', '%dx%d' % (options.frame_width, options.frame_height),
    '-i', '%s' % os.path.join(test_file_location, test_file_name),
    '-vf', '%s' % options.test_crop_parameters,
    '-c:a', 'copy',
    cropped_test_file
  ]

  ref_crop = subprocess.Popen(ref_video_crop_cmd)
  ref_crop.wait()
  test_crop = subprocess.Popen(test_video_crop_cmd)
  test_crop.wait()

  # ffmpeg does not abort when it fails, need to check return code.
  if ref_crop.returncode != 0 or test_crop.returncode != 0:
    # Cleanup recording directories.
    shutil.rmtree(ref_file_location)
    shutil.rmtree(test_file_location)
    raise FfmpegError('Cropping failed, check ffmpeg output.')
  else:
    print 'Ref file cropped to: ' + cropped_ref_file
    print 'Test file cropped to: ' + cropped_test_file
    print 'Cropping done!\n'

    # Need to return these so they can be used by other parts.
    cropped_recordings = {
      'cropped_test_file' : cropped_test_file,
      'cropped_ref_file' : cropped_ref_file
    }
    return cropped_recordings


def CompareVideos(options, cropped_ref_file, cropped_test_file):
  """Runs the compare_video.py script from src/webrtc/rtc_tools using path.

  Uses the path from recording_result and writes the output to a file named
  <options.app_name + '_' + CURRENT_TIME + '_result.txt> in the reference video
  recording folder taken from recording_result.

  Args:
    options(object): Contains all the provided command line options.
    cropped_ref_file(string): Path to cropped reference video file.
    cropped_test_file(string): Path to cropped test video file.

  Raises:
    CompareVideosError: If compare_videos.py fails.
  """
  print 'Starting comparison...'
  print 'Grab a coffee, this might take a few minutes...'
  compare_videos_script = os.path.abspath(options.compare_videos_script)
  rec_path = os.path.abspath(os.path.join(
    os.path.dirname(cropped_test_file)))
  result_file_name = os.path.join(rec_path, '%s_%s_result.txt') % (
    options.app_name, CURRENT_TIME)

  # Find the crop dimensions (e.g. 950 and 420) in the ref crop parameter
  # string: 'hflip, crop=950:420:130:56'
  for param in options.ref_crop_parameters.split('crop'):
    if param[0] == '=':
      crop_width = int(param.split(':')[0].split('=')[1])
      crop_height = int(param.split(':')[1])

  compare_cmd = [
    compare_videos_script,
    '--ref_video=%s' % cropped_ref_file,
    '--test_video=%s' % cropped_test_file,
    '--frame_analyzer=%s' % os.path.abspath(options.frame_analyzer),
    '--zxing_path=%s' % options.zxing_path,
    '--ffmpeg_path=%s' % options.ffmpeg,
    '--stats_file_ref=%s_stats.txt' %
        os.path.join(os.path.dirname(cropped_ref_file), cropped_ref_file),
    '--stats_file_test=%s_stats.txt' %
        os.path.join(os.path.dirname(cropped_test_file), cropped_test_file),
    '--yuv_frame_height=%d' % crop_height,
    '--yuv_frame_width=%d' % crop_width
  ]

  with open(result_file_name, 'w') as f:
    try:
      compare_video_recordings = subprocess.check_output(compare_cmd)
      f.write(compare_video_recordings)
    except subprocess.CalledProcessError as error:
      raise CompareVideosError('Failed to perform comparison: %s' % error)
    else:
      print 'Result recorded to: %s' % os.path.abspath(result_file_name)
      print 'Comparison done!'
      return compare_video_recordings


def main():
  """The main function.

  A simple invocation is:
  ./run_video_analysis.py \
    --app_name AppRTCMobile \
    --ffmpeg ./ffmpeg --ref_video_device=/dev/video0 \
    --test_video_device=/dev/video1 \
    --zxing_path ./zxing \
    --test_crop_parameters 'crop=950:420:130:56' \
    --ref_crop_parameters 'hflip, crop=950:420:130:56' \
    --ref_rec_dir /tmp/ref \
    --test_rec_dir /tmp/test

  This will produce the following files if successful:
  # Original video recordings.
  /tmp/ref/AppRTCMobile_<recording date and time>_ref.yuv
  /tmp/test/AppRTCMobile_<recording date and time>_test.yuv

  # Cropped video recordings according to the crop parameters.
  /tmp/ref/cropped_AppRTCMobile_<recording date and time>_ref.yuv
  /tmp/test/cropped_AppRTCMobile_<recording date and time>_ref.yuv

  # Comparison metrics from cropped test and ref videos.
  /tmp/test/AppRTCMobile_<recording date and time>_result.text

  """
  options = _ParseArgs()
  RestartMagewellDevices(options.ref_video_device, options.test_video_device)
  record_paths = CreateRecordingDirs(options)
  recording_result = StartRecording(options, record_paths['ref_rec_location'],
                                    record_paths['test_rec_location'])

  # Do not require compare_video.py script to run, no metrics will be generated.
  if options.compare_videos_script:
    CompareVideos(options, recording_result['cropped_ref_file'],
                  recording_result['cropped_test_file'])
  else:
    print ('Skipping compare videos step due to compare_videos flag were not '
           'passed.')


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