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

"""Produces configured shell abstractions.

This module knows how to produce a configured shell abstraction based on
shell_config.ShellConfig.
"""

import os.path
import sys
import urlparse

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

# 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


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


def _host_local_url_destination(shell, dest_file, port, free_host_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')
  mappings = [('', [directory])]
  server_url = shell.serve_local_directories(mappings, port, free_host_port)
  return server_url + os.path.relpath(dest_file, directory)


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

  Returns:
    Url of the hosted directory.
  """
  mappings = [('', [dest_dir])]
  return shell.serve_local_directories(mappings, port, free_host_port)


def _rewrite(mapping, host_destination_functon, shell, port, free_host_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, free_host_port)
  return src + '=' + dest


def _apply_mappings(shell, original_arguments, map_urls, map_origins,
                    free_ports, free_host_ports):
  """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>.
    free_ports: Iff True, run local development servers on system-allocated
        ports. This defeats any performance benefits from caching.
    free_host_ports: Only applicable on Android. Iff True, local development
        servers are run on system-allocated ports, but are still forwarded from
        fixed ports on the device.

  Returns:
    The updated argument list.
  """
  next_port = 0 if free_ports else _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,
                         free_host_ports)
      if not free_ports:
        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, free_host_ports)
      if not free_ports:
        next_port += 1
      # Origin mappings are specified as separate, repeated shell arguments.
      args.append('--map-origin=' + mapping)
  return args


def configure_local_origin(shell, local_dir, port, free_host_port):
  """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.
  """
  mappings = [('', [local_dir])]
  origin_url = shell.serve_local_directories(mappings, port, free_host_port)
  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 _configure_dev_server(shell, shell_args, dev_server_config, free_host_port,
                          verbose):
  """Sets up a dev server on the host according to |dev_server_config|.

  Args:
    shell: The shell that is being configured.
    shell_arguments: Current list of shell arguments.
    dev_server_config: Instance of shell_config.DevServerConfig describing the
        dev server to be set up.

  Returns:
    The updated argument list.
  """
  port = dev_server_config.port if dev_server_config.port else 0
  server_url = shell.serve_local_directories(dev_server_config.mappings,
                                             port=port,
                                             free_host_port=free_host_port)
  shell_args.append('--map-origin=%s=%s' % (dev_server_config.host, server_url))

  if verbose:
    print "Configured %s locally at %s to serve:" % (dev_server_config.host,
                                                     server_url)
    for mapping_prefix, mapping_path in dev_server_config.mappings:
      print "  /%s -> %s" % (mapping_prefix, mapping_path)
  return shell_args


def get_shell(shell_config, shell_args):
  """
  Produces a shell abstraction configured according to |shell_config|.

  Args:
    shell_config: Instance of shell_config.ShellConfig.
    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). |shell| is the configured shell abstraction,
    |shell_args| is updated list of shell arguments.

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

    shell = AndroidShell(shell_config.adb_path, shell_config.target_device,
                         logcat_tags=shell_config.logcat_tags,
                         verbose_pipe=verbose_pipe)

    device_status, error = shell.check_device(
        require_root=shell_config.require_root)
    if not device_status:
      raise ShellConfigurationException('Device check failed: ' + error)
    if shell_config.shell_path:
      shell.install_apk(shell_config.shell_path)
  else:
    if not shell_config.shell_path:
      raise ShellConfigurationException('Can not run without a shell binary. '
                                        'Please pass --shell-path.')
    shell = LinuxShell(shell_config.shell_path)
    if shell_config.use_osmesa:
      shell_args.append('--args-for=mojo:native_viewport_service --use-osmesa')

  shell_args = _apply_mappings(shell, shell_args, shell_config.map_url_list,
                               shell_config.map_origin_list,
                               shell_config.free_ports,
                               shell_config.free_host_ports)

  if shell_config.origin:
    if _is_web_url(shell_config.origin):
      shell_args.append('--origin=' + shell_config.origin)
    else:
      local_origin_port = 0 if shell_config.free_ports else _LOCAL_ORIGIN_PORT
      shell_args.extend(configure_local_origin(shell, shell_config.origin,
                                               local_origin_port,
                                               shell_config.free_host_ports))

  if shell_config.content_handlers:
    for (mime_type,
         content_handler_url) in shell_config.content_handlers.iteritems():
      shell_args = append_to_argument(shell_args, '--content-handlers=',
                                      '%s,%s' % (mime_type,
                                                 content_handler_url))

  for dev_server_config in shell_config.dev_servers:
    shell_args = _configure_dev_server(shell, shell_args, dev_server_config,
                                       shell_config.free_host_ports,
                                       shell_config.verbose)

  return shell, shell_args
