# Copyright 2015 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.

"""Functions that configure the shell before it is run manipulating its argument
list.
"""

import os.path
import sys
import urlparse

from devtoolslib.android_shell import AndroidShell
from devtoolslib.linux_shell import LinuxShell

# When spinning up servers for local origins, we want to use predictable ports
# so that caching works between subsequent runs with the same command line.
_LOCAL_ORIGIN_PORT = 31840
_MAPPINGS_BASE_PORT = 31841
_SKY_SERVER_PORT = 9998


def _is_web_url(dest):
  return True if urlparse.urlparse(dest).scheme else False


def _host_local_url_destination(shell, dest_file, port):
  """Starts a local server to host |dest_file|.

  Returns:
    Url of the hosted file.
  """
  directory = os.path.dirname(dest_file)
  if not os.path.exists(directory):
    raise ValueError('local path passed as --map-url destination '
                     'does not exist')
  server_url = shell.ServeLocalDirectory(directory, port)
  return server_url + os.path.relpath(dest_file, directory)


def _host_local_origin_destination(shell, dest_dir, port):
  """Starts a local server to host |dest_dir|.

  Returns:
    Url of the hosted directory.
  """
  return shell.ServeLocalDirectory(dest_dir, port)


def _rewrite(mapping, host_destination_functon, shell, port):
  """Takes a mapping given as <src>=<dest> and rewrites the <dest> part to be
  hosted locally using the given function if <dest> is not a web url.
  """
  parts = mapping.split('=')
  if len(parts) != 2:
    raise ValueError('each mapping value should be in format '
                     '"<url>=<url-or-local-path>"')
  if _is_web_url(parts[1]):
    # The destination is a web url, do nothing.
    return mapping

  src = parts[0]
  dest = host_destination_functon(shell, parts[1], port)
  return src + '=' + dest


def _apply_mappings(shell, original_arguments, map_urls, map_origins):
  """Applies mappings for specified urls and origins. For each local path
  specified as destination a local server will be spawned and the mapping will
  be rewritten accordingly.

  Args:
    shell: The shell that is being configured.
    original_arguments: Current list of shell arguments.
    map_urls: List of url mappings, each in the form of
      <url>=<url-or-local-path>.
    map_origins: List of origin mappings, each in the form of
        <origin>=<url-or-local-path>.

  Returns:
    The updated argument list.
  """
  next_port = _MAPPINGS_BASE_PORT
  args = original_arguments
  if map_urls:
    # Sort the mappings to preserve caching regardless of argument order.
    for map_url in sorted(map_urls):
      mapping = _rewrite(map_url, _host_local_url_destination, shell, next_port)
      next_port += 1
      # All url mappings need to be coalesced into one shell argument.
      args = append_to_argument(args, '--url-mappings=', mapping)

  if map_origins:
    for map_origin in sorted(map_origins):
      mapping = _rewrite(map_origin, _host_local_origin_destination, shell,
                         next_port)
      next_port += 1
      # Origin mappings are specified as separate, repeated shell arguments.
      args.append('--map-origin=' + mapping)
  return args


def _configure_sky(shell_args):
  """Maps mojo:sky_viewer as a content handler for dart applications.
  app.

  Args:
    shell_args: Current list of shell arguments.

  Returns:
    Updated list of shell arguments.
  """
  # Configure the content type mappings for the sky_viewer. This is needed
  # only for the Sky apps that do not declare mojo:sky_viewer in a shebang.
  # TODO(ppi): drop this part once we can rely on the Sky files declaring
  # correct shebang.
  shell_args = append_to_argument(shell_args, '--content-handlers=',
                                            'text/sky,mojo:sky_viewer')
  shell_args = append_to_argument(shell_args, '--content-handlers=',
                                            'application/dart,mojo:sky_viewer')
  return shell_args


def configure_local_origin(shell, local_dir, fixed_port=True):
  """Sets up a local http server to serve files in |local_dir| along with
  device port forwarding if needed.

  Returns:
    The list of arguments to be appended to the shell argument list.
  """

  origin_url = shell.ServeLocalDirectory(
      local_dir, _LOCAL_ORIGIN_PORT if fixed_port else 0)
  return ["--origin=" + origin_url]


def append_to_argument(arguments, key, value, delimiter=","):
  """Looks for an argument of the form "key=val1,val2" within |arguments| and
  appends |value| to it.

  If the argument is not present in |arguments| it is added.

  Args:
    arguments: List of arguments for the shell.
    key: Identifier of the argument, including the equal sign, eg.
        "--content-handlers=".
    value: The value to be appended, after |delimeter|, to the argument.
    delimiter: The string used to separate values within the argument.

  Returns:
    The updated argument list.
  """
  assert key and key.endswith('=')
  assert value

  for i, argument in enumerate(arguments):
    if not argument.startswith(key):
      continue
    arguments[i] = argument + delimiter + value
    break
  else:
    arguments.append(key + value)

  return arguments


def add_shell_arguments(parser):
  """Adds argparse arguments allowing to configure shell abstraction using
  configure_shell() below.
  """
  # Arguments configuring the shell run.
  parser.add_argument('--shell-path', help='Path of the Mojo shell binary.')
  parser.add_argument('--android', help='Run on Android',
                      action='store_true')
  parser.add_argument('--origin', help='Origin for mojo: URLs. This can be a '
                      'web url or a local directory path.')
  parser.add_argument('--map-url', action='append',
                      help='Define a mapping for a url in the format '
                      '<url>=<url-or-local-file-path>')
  parser.add_argument('--map-origin', action='append',
                      help='Define a mapping for a url origin in the format '
                      '<origin>=<url-or-local-file-path>')
  parser.add_argument('--sky', action='store_true',
                      help='Maps mojo:sky_viewer as the content handler for '
                           'dart apps.')
  parser.add_argument('-v', '--verbose', action="store_true",
                      help="Increase output verbosity")

  android_group = parser.add_argument_group('Android-only',
      'These arguments apply only when --android is passed.')
  android_group.add_argument('--adb-path', help='Path of the adb binary.')
  android_group.add_argument('--target-device', help='Device to run on.')
  android_group.add_argument('--logcat-tags', help='Comma-separated list of '
                             'additional logcat tags to display.')

  desktop_group = parser.add_argument_group('Desktop-only',
      'These arguments apply only when running on desktop.')
  desktop_group.add_argument('--use-osmesa', action='store_true',
                             help='Configure the native viewport service '
                             'for off-screen rendering.')


class ShellConfigurationException(Exception):
  """Represents an error preventing creating a functional shell abstraction."""
  pass


def configure_shell(config_args, shell_args):
  """
  Produces a shell abstraction configured using the parsed arguments defined in
  add_shell_arguments().

  Args:
    config_args: Parsed arguments added using add_shell_arguments().
    shell_args: Additional raw shell arguments to be passed to the shell. We
        need to take these into account as some parameters need to appear only
        once on the argument list (e.g. url-mappings) so we need to coalesce any
        overrides and the existing value into just one argument.

  Returns:
    A tuple of (shell, shell_args).

  Throws:
    ShellConfigurationException if shell abstraction could not be configured.
  """
  if config_args.android:
    verbose_pipe = sys.stdout if config_args.verbose else None

    shell = AndroidShell(config_args.adb_path, config_args.target_device,
                         logcat_tags=config_args.logcat_tags,
                         verbose_pipe=verbose_pipe)
    device_status, error = shell.CheckDevice()
    if not device_status:
      raise ShellConfigurationException('Device check failed: ' + error)
    if config_args.shell_path:
      shell.InstallApk(config_args.shell_path)
  else:
    if not config_args.shell_path:
      raise ShellConfigurationException('Can not run without a shell binary. '
                                        'Please pass --shell-path.')
    shell = LinuxShell(config_args.shell_path)
    if config_args.use_osmesa:
      shell_args.append('--args-for=mojo:native_viewport_service --use-osmesa')

  shell_args = _apply_mappings(shell, shell_args, config_args.map_url,
                               config_args.map_origin)

  if config_args.origin:
    if _is_web_url(config_args.origin):
      shell_args.append('--origin=' + config_args.origin)
    else:
      shell_args.extend(configure_local_origin(shell, config_args.origin,
                                             fixed_port=True))

  if config_args.sky:
    shell_args = _configure_sky(shell_args)

  return shell, shell_args
