# Copyright 2014 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.
"""Manages intents and associated information.

This is generally intended to be used with functions that calls Android's
Am command.
"""

# Some common flag constants that can be used to construct intents.
# Full list: http://developer.android.com/reference/android/content/Intent.html
FLAG_ACTIVITY_CLEAR_TASK = 0x00008000
FLAG_ACTIVITY_CLEAR_TOP = 0x04000000
FLAG_ACTIVITY_NEW_TASK = 0x10000000
FLAG_ACTIVITY_REORDER_TO_FRONT = 0x00020000
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 0x00200000


def _bitwise_or(flags):
  result = 0
  for flag in flags:
    result |= flag
  return result


class Intent(object):
  def __init__(self,
               action='android.intent.action.VIEW',
               activity=None,
               category=None,
               component=None,
               data=None,
               extras=None,
               flags=None,
               package=None):
    """Creates an Intent.

    Args:
      action: A string containing the action.
      activity: A string that, with |package|, can be used to specify the
                component.
      category: A string or list containing any categories.
      component: A string that specifies the component to send the intent to.
      data: A string containing a data URI.
      extras: A dict containing extra parameters to be passed along with the
              intent.
      flags: A sequence of flag constants to be passed with the intent.
      package: A string that, with activity, can be used to specify the
               component.
    """
    self._action = action
    self._activity = activity
    if isinstance(category, list) or category is None:
      self._category = category
    else:
      self._category = [category]
    self._component = component
    self._data = data
    self._extras = extras
    self._flags = '0x%0.8x' % _bitwise_or(flags) if flags else None
    self._package = package

    if self._component and '/' in component:
      self._package, self._activity = component.split('/', 1)
    elif self._package and self._activity:
      self._component = '%s/%s' % (package, activity)

  @property
  def action(self):
    return self._action

  @property
  def activity(self):
    return self._activity

  @property
  def category(self):
    return self._category

  @property
  def component(self):
    return self._component

  @property
  def data(self):
    return self._data

  @property
  def extras(self):
    return self._extras

  @property
  def flags(self):
    return self._flags

  @property
  def package(self):
    return self._package

  @property
  def am_args(self):
    """Returns the intent as a list of arguments for the activity manager.

    For details refer to the specification at:
    - http://developer.android.com/tools/help/adb.html#IntentSpec
    """
    args = []
    if self.action:
      args.extend(['-a', self.action])
    if self.data:
      args.extend(['-d', self.data])
    if self.category:
      args.extend(arg for cat in self.category for arg in ('-c', cat))
    if self.component:
      args.extend(['-n', self.component])
    if self.flags:
      args.extend(['-f', self.flags])
    if self.extras:
      for key, value in self.extras.items():
        if value is None:
          args.extend(['--esn', key])
        elif isinstance(value, str):
          args.extend(['--es', key, value])
        elif isinstance(value, bool):
          args.extend(['--ez', key, str(value)])
        elif isinstance(value, int):
          args.extend(['--ei', key, str(value)])
        elif isinstance(value, float):
          args.extend(['--ef', key, str(value)])
        else:
          raise NotImplementedError(
              'Intent does not know how to pass %s extras' % type(value))
    return args
