# 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
