# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import os
import signal
import tempfile

from pylib import cmd_helper

# TODO(jbudorick) Remove once telemetry gets switched over.
import pylib.android_commands
import pylib.device.device_utils


class VideoRecorder(object):
  """Records a screen capture video from an Android Device (KitKat or newer).

  Args:
    device: DeviceUtils instance.
    host_file: Path to the video file to store on the host.
    megabits_per_second: Video bitrate in megabits per second. Allowed range
                         from 0.1 to 100 mbps.
    size: Video frame size tuple (width, height) or None to use the device
          default.
    rotate: If True, the video will be rotated 90 degrees.
  """
  def __init__(self, device, megabits_per_second=4, size=None,
               rotate=False):
    # TODO(jbudorick) Remove once telemetry gets switched over.
    if isinstance(device, pylib.android_commands.AndroidCommands):
      device = pylib.device.device_utils.DeviceUtils(device)
    self._device = device
    self._device_file = (
        '%s/screen-recording.mp4' % device.GetExternalStoragePath())
    self._recorder = None
    self._recorder_stdout = None
    self._is_started = False

    self._args = ['adb']
    if str(self._device):
      self._args += ['-s', str(self._device)]
    self._args += ['shell', 'screenrecord', '--verbose']
    self._args += ['--bit-rate', str(megabits_per_second * 1000 * 1000)]
    if size:
      self._args += ['--size', '%dx%d' % size]
    if rotate:
      self._args += ['--rotate']
    self._args += [self._device_file]

  def Start(self):
    """Start recording video."""
    self._recorder_stdout = tempfile.mkstemp()[1]
    self._recorder = cmd_helper.Popen(
        self._args, stdout=open(self._recorder_stdout, 'w'))
    if not self._device.GetPids('screenrecord'):
      raise RuntimeError('Recording failed. Is your device running Android '
                         'KitKat or later?')

  def IsStarted(self):
    if not self._is_started:
      for line in open(self._recorder_stdout):
        self._is_started = line.startswith('Content area is ')
        if self._is_started:
          break
    return self._is_started

  def Stop(self):
    """Stop recording video."""
    os.remove(self._recorder_stdout)
    self._is_started = False
    if not self._recorder:
      return
    self._device.KillAll('screenrecord', signum=signal.SIGINT)
    self._recorder.wait()

  def Pull(self, host_file=None):
    """Pull resulting video file from the device.

    Args:
      host_file: Path to the video file to store on the host.
    Returns:
      Output video file name on the host.
    """
    host_file_name = host_file or ('screen-recording-%s.mp4' %
                                   self._device.old_interface.GetTimestamp())
    host_file_name = os.path.abspath(host_file_name)
    self._device.old_interface.EnsureHostDirectory(host_file_name)
    self._device.PullFile(self._device_file, host_file_name)
    self._device.RunShellCommand('rm -f "%s"' % self._device_file)
    return host_file_name
