# 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_appings(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, root_path, sky_packages_path, sky_target):
  """Configures additional mappings and a server needed to run the given Sky
  app.

  Args:
    root_path: Local path to the root from which Sky apps will be served.
    sky_packages_path: Local path to the root from which Sky packages will be
        served.
    sky_target: Path to the Sky app to be run, relative to |root_path|.

  Returns:
    Arguments that need to be appended to the shell argument list.
  """
  # Configure a server to serve the checkout root at / (so that Sky examples
  # are accessible using a root-relative path) and Sky packages at /packages.
  # This is independent from the server that potentially serves the origin
  # directory containing the mojo: apps.
  additional_mappings = [
      ('packages/', sky_packages_path),
  ]
  server_url = shell.ServeLocalDirectory(root_path, port=_SKY_SERVER_PORT,
      additional_mappings=additional_mappings)

  args = []
  # 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,
  # and it is unfortunate as it configures the shell to map all items of the
  # application/dart content-type as Sky apps.
  # TODO(ppi): drop this part once we can rely on the Sky files declaring
  # correct shebang.
  args = append_to_argument(args, '--content-handlers=',
                                            'text/sky,mojo:sky_viewer')
  args = append_to_argument(args, '--content-handlers=',
                                            'application/dart,mojo:sky_viewer')

  # Configure the window manager to embed the sky_viewer.
  sky_url = server_url + sky_target
  args.append('mojo:window_manager %s' % sky_url)
  return 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 indicating paths to binaries and tools.
  parser.add_argument('--adb-path', help='Path of the adb binary.')
  parser.add_argument('--shell-path', help='Path of the Mojo shell binary.')

  # Arguments configuring the shell run.
  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>')

  # Android-only arguments.
  parser.add_argument('--target-device',
                      help='(android-only) Device to run on.')
  parser.add_argument('--logcat-tags',
                      help='(android-only) Comma-separated list of additional '
                      'logcat tags to display on the console.')

  # Desktop-only arguments.
  parser.add_argument('--use-osmesa', action='store_true',
                      help='(linux-only) Configure the native viewport service '
                      'for off-screen rendering.')

  # Other configuration.
  parser.add_argument('-v', '--verbose', action="store_true",
                      help="Increase output verbosity")


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)

    shell_args = _apply_appings(shell, shell_args, config_args.map_url,
                                config_args.map_origin)
  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')

  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))

  return shell, shell_args
