# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""JSON RPC interface to android scripting engine."""

import time

from mobly import utils
from mobly.controllers.android_device_lib import event_dispatcher
from mobly.controllers.android_device_lib import jsonrpc_client_base

_APP_NAME = 'SL4A'
_DEVICE_SIDE_PORT = 8080
_LAUNCH_CMD = (
    'am start -a com.googlecode.android_scripting.action.LAUNCH_SERVER '
    '--ei com.googlecode.android_scripting.extra.USE_SERVICE_PORT %s '
    'com.googlecode.android_scripting/.activity.ScriptingLayerServiceLauncher')
# Maximum time to wait for the app to start on the device (10 minutes).
# TODO: This timeout is set high in order to allow for retries in
# start_app_and_connect. Decrease it when the call to connect() has the option
# for a quicker timeout than the default _cmd() timeout.
# TODO: Evaluate whether the high timeout still makes sense for sl4a. It was
# designed for user snippets which could be very slow to start depending on the
# size of the snippet and main apps. sl4a can probably use a much smaller value.
_APP_START_WAIT_TIME = 2 * 60


class Sl4aClient(jsonrpc_client_base.JsonRpcClientBase):
  """A client for interacting with SL4A using Mobly Snippet Lib.

  Extra public attributes:
  ed: Event dispatcher instance for this sl4a client.
  """

  def __init__(self, ad):
    """Initializes an Sl4aClient.

    Args:
      ad: AndroidDevice object.
    """
    super(Sl4aClient, self).__init__(app_name=_APP_NAME, ad=ad)
    self._ad = ad
    self.ed = None
    self._adb = ad.adb

  def start_app_and_connect(self):
    """Overrides superclass."""
    # Check that sl4a is installed
    out = self._adb.shell('pm list package')
    if not utils.grep('com.googlecode.android_scripting', out):
      raise jsonrpc_client_base.AppStartError(
          self._ad, '%s is not installed on %s' % (_APP_NAME, self._adb.serial))
    self.disable_hidden_api_blacklist()

    # sl4a has problems connecting after disconnection, so kill the apk and
    # try connecting again.
    try:
      self.stop_app()
    except Exception as e:
      self.log.warning(e)

    # Launch the app
    self.device_port = _DEVICE_SIDE_PORT
    self._adb.shell(_LAUNCH_CMD % self.device_port)

    # Try to start the connection (not restore the connectivity).
    # The function name restore_app_connection is used here is for the
    # purpose of reusing the same code as it does when restoring the
    # connection. And we do not want to come up with another function
    # name to complicate the API. Change the name if necessary.
    self.restore_app_connection()

  def restore_app_connection(self, port=None):
    """Restores the sl4a after device got disconnected.

    Instead of creating new instance of the client:
      - Uses the given port (or find a new available host_port if none is
      given).
      - Tries to connect to remote server with selected port.

    Args:
      port: If given, this is the host port from which to connect to remote
        device port. If not provided, find a new available port as host
        port.

    Raises:
      AppRestoreConnectionError: When the app was not able to be started.
    """
    self.host_port = port or utils.get_available_host_port()
    self._retry_connect()
    self.ed = self._start_event_client()

  def stop_app(self):
    """Overrides superclass."""
    try:
      if self._conn:
        # Be polite; let the dest know we're shutting down.
        try:
          self.closeSl4aSession()
        except:
          self.log.exception('Failed to gracefully shut down %s.',
                             self.app_name)

        # Close the socket connection.
        self.disconnect()
        self.stop_event_dispatcher()

      # Terminate the app
      self._adb.shell('am force-stop com.googlecode.android_scripting')
    finally:
      # Always clean up the adb port
      self.clear_host_port()

  def stop_event_dispatcher(self):
    # Close Event Dispatcher
    if self.ed:
      try:
        self.ed.clean_up()
      except:
        self.log.exception('Failed to shutdown sl4a event dispatcher.')
      self.ed = None

  def _retry_connect(self):
    self._adb.forward(['tcp:%d' % self.host_port, 'tcp:%d' % self.device_port])
    start_time = time.time()
    expiration_time = start_time + _APP_START_WAIT_TIME
    started = False
    while time.time() < expiration_time:
      self.log.debug('Attempting to start %s.', self.app_name)
      try:
        self.connect()
        started = True
        break
      except:
        self.log.debug('%s is not yet running, retrying',
                       self.app_name,
                       exc_info=True)
      time.sleep(1)
    if not started:
      raise jsonrpc_client_base.AppRestoreConnectionError(
          self._ad, '%s failed to connect for %s at host port %s, '
          'device port %s' %
          (self.app_name, self._adb.serial, self.host_port, self.device_port))

  def _start_event_client(self):
    # Start an EventDispatcher for the current sl4a session
    event_client = Sl4aClient(self._ad)
    event_client.host_port = self.host_port
    event_client.device_port = self.device_port
    event_client.connect(uid=self.uid,
                         cmd=jsonrpc_client_base.JsonRpcCommand.CONTINUE)
    ed = event_dispatcher.EventDispatcher(event_client)
    ed.start()
    return ed
