# Copyright 2016 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 collections
import contextlib
import logging
import os
import shutil
import subprocess
import sys
import tempfile
import time

_SRC_DIR = os.path.abspath(os.path.join(
    os.path.dirname(__file__), '..', '..', '..'))

_CATAPULT_DIR = os.path.join(_SRC_DIR, 'third_party', 'catapult')
sys.path.append(os.path.join(_CATAPULT_DIR, 'devil'))
from devil.android import device_utils
from devil.android import forwarder
from devil.android.sdk import adb_wrapper
from devil.android.sdk import intent
from devil.android.sdk import keyevent

sys.path.append(os.path.join(_SRC_DIR, 'build', 'android'))
from pylib import constants
from video_recorder import video_recorder

sys.path.append(os.path.join(_SRC_DIR, 'tools', 'perf'))
from core import path_util
sys.path.append(path_util.GetTelemetryDir())

from telemetry.internal.image_processing import video
from telemetry.internal.util import wpr_server

sys.path.append(os.path.join(
    _CATAPULT_DIR, 'telemetry', 'third_party', 'webpagereplay'))
import adb_install_cert
import certutils

import common_util
import devtools_monitor
import emulation
import options


OPTIONS = options.OPTIONS

# The speed index's video recording's bit rate in Mb/s.
_SPEED_INDEX_VIDEO_BITRATE = 4


class DeviceSetupException(Exception):
  def __init__(self, msg):
    super(DeviceSetupException, self).__init__(msg)
    logging.error(msg)


def GetFirstDevice():
  """Returns the first connected device.

  Raises:
    DeviceSetupException if there is no such device.
  """
  devices = device_utils.DeviceUtils.HealthyDevices()
  if not devices:
    raise DeviceSetupException('No devices found')
  return devices[0]


def GetDeviceFromSerial(android_device_serial):
  """Returns the DeviceUtils instance."""
  devices = device_utils.DeviceUtils.HealthyDevices()
  for device in devices:
    if device.adb._device_serial == android_device_serial:
      return device
  raise DeviceSetupException(
      'Device {} not found'.format(android_device_serial))


def Reboot(device):
  """Reboot the device.

  Args:
    device: Device to reboot, from DeviceUtils.
  """
  # Kills the device -> host forwarder running on the device so that
  # forwarder.Forwarder have correct state tracking after having rebooted.
  forwarder.Forwarder.UnmapAllDevicePorts(device)
  # Reboot the device.
  device.Reboot()
  # Pass through the lock screen.
  time.sleep(3)
  device.SendKeyEvent(keyevent.KEYCODE_MENU)


def DeviceSubmitShellCommandQueue(device, command_queue):
  """Executes on the device a command queue.

  Args:
    device: The device to execute the shell commands to.
    command_queue: a list of commands to be executed in that order.
  """
  REMOTE_COMMAND_FILE_PATH = '/data/local/tmp/adb_command_file.sh'
  if not command_queue:
    return
  with tempfile.NamedTemporaryFile(prefix='adb_command_file_',
                                   suffix='.sh') as command_file:
    command_file.write('#!/bin/sh\n')
    command_file.write('# Shell file generated by {}\'s {}\n'.format(
        __file__, DeviceSubmitShellCommandQueue.__name__))
    command_file.write('set -e\n')
    for command in command_queue:
      command_file.write(subprocess.list2cmdline(command) + ' ;\n')
    command_file.write('exit 0;\n'.format(
        REMOTE_COMMAND_FILE_PATH))
    command_file.flush()
    device.adb.Push(command_file.name, REMOTE_COMMAND_FILE_PATH)
    device.adb.Shell('sh {p} && rm {p}'.format(p=REMOTE_COMMAND_FILE_PATH))


@contextlib.contextmanager
def ForwardPort(device, local, remote):
  """Forwards a local port to a remote one on a device in a context."""
  # If we're logging requests from a local desktop chrome instance there is no
  # device.
  if not device:
    yield
    return
  device.adb.Forward(local, remote)
  try:
    yield
  finally:
    device.adb.ForwardRemove(local)


# WPR specific attributes to set up chrome.
#
# Members:
#   chrome_args: Additional flags list that may be used for chromium to load web
#     page through the running web page replay host.
#   chrome_env_override: Dictionary of environment variables to override at
#     Chrome's launch time.
WprAttribute = collections.namedtuple('WprAttribute',
                                      ['chrome_args', 'chrome_env_override'])


@contextlib.contextmanager
def _WprHost(wpr_archive_path, record=False,
             network_condition_name=None,
             disable_script_injection=False,
             wpr_ca_cert_path=None,
             out_log_path=None):
  assert wpr_archive_path

  def PathWorkaround(path):
    # webpagereplay.ReplayServer is doing a os.path.exist(os.path.dirname(p))
    # that fails if p = 'my_file.txt' because os.path.dirname(p) = '' != '.'.
    # This workaround just sends absolute path to work around this bug.
    return os.path.abspath(path)

  wpr_server_args = ['--use_closest_match']
  if record:
    wpr_server_args.append('--record')
    if os.path.exists(wpr_archive_path):
      os.remove(wpr_archive_path)
  else:
    assert os.path.exists(wpr_archive_path)
  if network_condition_name:
    condition = emulation.NETWORK_CONDITIONS[network_condition_name]
    if record:
      logging.warning('WPR network condition is ignored when recording.')
    else:
      wpr_server_args.extend([
          '--down', emulation.BandwidthToString(condition['download']),
          '--up', emulation.BandwidthToString(condition['upload']),
          '--delay_ms', str(condition['latency']),
          '--shaping_type', 'proxy'])

  if disable_script_injection:
    # Remove default WPR injected scripts like deterministic.js which
    # overrides Math.random.
    wpr_server_args.extend(['--inject_scripts', ''])
  if wpr_ca_cert_path:
    wpr_server_args.extend(['--should_generate_certs',
        '--https_root_ca_cert_path=' + PathWorkaround(wpr_ca_cert_path)])
  if out_log_path:
    # --log_level debug to extract the served URLs requests from the log.
    wpr_server_args.extend(['--log_level', 'debug',
                            '--log_file', PathWorkaround(out_log_path)])
    # Don't append to previously existing log.
    if os.path.exists(out_log_path):
      os.remove(out_log_path)

  # Set up WPR server and device forwarder.
  server = wpr_server.ReplayServer(PathWorkaround(wpr_archive_path),
      '127.0.0.1', 0, 0, None, wpr_server_args)
  http_port, https_port = server.StartServer()[:-1]

  logging.info('WPR server listening on HTTP=%s, HTTPS=%s (options=%s)' % (
      http_port, https_port, wpr_server_args))
  try:
    yield http_port, https_port
  finally:
    server.StopServer()


def _VerifySilentWprHost(record, network_condition_name):
  assert not record, 'WPR cannot record without a specified archive.'
  assert not network_condition_name, ('WPR cannot emulate network condition' +
                                      ' without a specified archive.')


def _FormatWPRRelatedChromeArgumentFor(http_port, https_port):
  HOST_RULES='MAP * 127.0.0.1,EXCLUDE localhost'
  return [
      '--testing-fixed-http-port={}'.format(http_port),
      '--testing-fixed-https-port={}'.format(https_port),
      '--host-resolver-rules={}'.format(HOST_RULES)]


@contextlib.contextmanager
def LocalWprHost(wpr_archive_path, record=False,
                 network_condition_name=None,
                 disable_script_injection=False,
                 out_log_path=None):
  """Launches web page replay host.

  Args:
    wpr_archive_path: host sided WPR archive's path.
    record: Enables or disables WPR archive recording.
    network_condition_name: Network condition name available in
        emulation.NETWORK_CONDITIONS.
    disable_script_injection: Disable JavaScript file injections that is
      fighting against resources name entropy.
    out_log_path: Path of the WPR host's log.

  Returns:
    WprAttribute
  """
  if wpr_archive_path == None:
    _VerifySilentWprHost(record, network_condition_name)
    yield []
    return

  with common_util.TemporaryDirectory() as temp_home_dir:
    # Generate a root certification authority certificate for WPR.
    private_ca_cert_path = os.path.join(temp_home_dir, 'wpr.pem')
    ca_cert_path = os.path.join(temp_home_dir, 'wpr-cert.pem')
    certutils.write_dummy_ca_cert(*certutils.generate_dummy_ca_cert(),
                                  cert_path=private_ca_cert_path)
    assert os.path.isfile(ca_cert_path)
    certutils.install_cert_in_nssdb(temp_home_dir, ca_cert_path)

    with _WprHost(
        wpr_archive_path,
        record=record,
        network_condition_name=network_condition_name,
        disable_script_injection=disable_script_injection,
        wpr_ca_cert_path=private_ca_cert_path,
        out_log_path=out_log_path) as (http_port, https_port):
      chrome_args = _FormatWPRRelatedChromeArgumentFor(http_port, https_port)
      yield WprAttribute(chrome_args=chrome_args,
                         chrome_env_override={'HOME': temp_home_dir})


@contextlib.contextmanager
def RemoteWprHost(device, wpr_archive_path, record=False,
                  network_condition_name=None,
                  disable_script_injection=False,
                  out_log_path=None):
  """Launches web page replay host.

  Args:
    device: Android device.
    wpr_archive_path: host sided WPR archive's path.
    record: Enables or disables WPR archive recording.
    network_condition_name: Network condition name available in
        emulation.NETWORK_CONDITIONS.
    disable_script_injection: Disable JavaScript file injections that is
      fighting against resources name entropy.
    out_log_path: Path of the WPR host's log.

  Returns:
    WprAttribute
  """
  assert device
  if wpr_archive_path == None:
    _VerifySilentWprHost(record, network_condition_name)
    yield []
    return
  # Deploy certification authority to the device.
  temp_certificate_dir = tempfile.mkdtemp()
  wpr_ca_cert_path = os.path.join(temp_certificate_dir, 'testca.pem')
  certutils.write_dummy_ca_cert(*certutils.generate_dummy_ca_cert(),
                                cert_path=wpr_ca_cert_path)
  device_cert_util = adb_install_cert.AndroidCertInstaller(
      device.adb.GetDeviceSerial(), None, wpr_ca_cert_path,
      adb_wrapper.AdbWrapper.GetAdbPath())
  device_cert_util.install_cert(overwrite_cert=True)
  try:
    # Set up WPR server
    with _WprHost(
        wpr_archive_path,
        record=record,
        network_condition_name=network_condition_name,
        disable_script_injection=disable_script_injection,
        wpr_ca_cert_path=wpr_ca_cert_path,
        out_log_path=out_log_path) as (http_port, https_port):
      # Set up the forwarder.
      forwarder.Forwarder.Map([(0, http_port), (0, https_port)], device)
      device_http_port = forwarder.Forwarder.DevicePortForHostPort(http_port)
      device_https_port = forwarder.Forwarder.DevicePortForHostPort(https_port)
      try:
        chrome_args = _FormatWPRRelatedChromeArgumentFor(device_http_port,
                                                         device_https_port)
        yield WprAttribute(chrome_args=chrome_args, chrome_env_override={})
      finally:
        # Tear down the forwarder.
        forwarder.Forwarder.UnmapDevicePort(device_http_port, device)
        forwarder.Forwarder.UnmapDevicePort(device_https_port, device)
  finally:
    # Remove certification authority from the device.
    device_cert_util.remove_cert()
    shutil.rmtree(temp_certificate_dir)


# Deprecated
@contextlib.contextmanager
def _RemoteVideoRecorder(device, local_output_path, megabits_per_second):
  """Record a video on Device.

  Args:
    device: (device_utils.DeviceUtils) Android device to connect to.
    local_output_path: Output path were to save the video locally.
    megabits_per_second: Video recorder Mb/s.

  Yields:
    None
  """
  assert device
  if megabits_per_second > 100:
    raise ValueError('Android video capture cannot capture at %dmbps. '
                     'Max capture rate is 100mbps.' % megabits_per_second)
  assert local_output_path.endswith('.mp4')
  recorder = video_recorder.VideoRecorder(device, megabits_per_second)
  recorder.Start()
  try:
    yield
    recorder.Stop()
    recorder.Pull(host_file=local_output_path)
    recorder = None
  finally:
    if recorder:
      recorder.Stop()


@contextlib.contextmanager
def RemoteSpeedIndexRecorder(device, connection, local_output_path):
  """Records on a device a video compatible for speed-index computation.

  Note:
    Chrome should be opened with the --disable-infobars command line argument to
    avoid web page viewport size to be changed, that can change speed-index
    value.

  Args:
    device: (device_utils.DeviceUtils) Android device to connect to.
    connection: devtools connection.
    local_output_path: Output path were to save the video locally.

  Yields:
    None
  """
  # Paint the current HTML document with the ORANGE that video is detecting with
  # the view-port position and size.
  color = video.HIGHLIGHT_ORANGE_FRAME
  connection.ExecuteJavaScript("""
    (function() {
      var screen = document.createElement('div');
      screen.style.background = 'rgb(%d, %d, %d)';
      screen.style.position = 'fixed';
      screen.style.top = '0';
      screen.style.left = '0';
      screen.style.width = '100%%';
      screen.style.height = '100%%';
      screen.style.zIndex = '2147483638';
      document.body.appendChild(screen);
      requestAnimationFrame(function() {
        requestAnimationFrame(function() {
          window.__speedindex_screen = screen;
        });
      });
    })();
  """ % (color.r, color.g, color.b))
  connection.PollForJavaScriptExpression('!!window.__speedindex_screen', 1)

  with _RemoteVideoRecorder(device, local_output_path,
                            megabits_per_second=_SPEED_INDEX_VIDEO_BITRATE):
    # Paint the current HTML document with white so that it is not troubling the
    # speed index measurement.
    connection.ExecuteJavaScript("""
      (function() {
        requestAnimationFrame(function() {
          var screen = window.__speedindex_screen;
          screen.style.background = 'rgb(255, 255, 255)';
        });
      })();
    """)
    yield
