# 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.
"""Shared library for frontends to jsonrpc servers."""
from __future__ import print_function

import code
import os
import pprint
import sys

from mobly.controllers import android_device


class Error(Exception):
  pass


class JsonRpcShellBase(object):
  def _start_services(self, console_env):
    """Starts the services needed by this client and adds them to console_env.

    Must be implemented by subclasses.
    """
    raise NotImplemented()

  def _get_banner(self, serial):
    """Returns the user-friendly banner message to print before the console.

    Must be implemented by subclasses.
    """
    raise NotImplemented()

  def load_device(self, serial=None):
    """Creates an AndroidDevice for the given serial number.

    If no serial is given, it will read from the ANDROID_SERIAL
    environmental variable. If the environmental variable is not set, then
    it will read from 'adb devices' if there is only one.
    """
    serials = android_device.list_adb_devices()
    if not serials:
      raise Error('No adb device found!')
    # No serial provided, try to pick up the device automatically.
    if not serial:
      env_serial = os.environ.get('ANDROID_SERIAL', None)
      if env_serial is not None:
        serial = env_serial
      elif len(serials) == 1:
        serial = serials[0]
      else:
        raise Error(
          'Expected one phone, but %d found. Use the -s flag or '
          'specify ANDROID_SERIAL.' % len(serials))
    if serial not in serials:
      raise Error('Device "%s" is not found by adb.' % serial)
    ads = android_device.get_instances([serial])
    assert len(ads) == 1
    self._ad = ads[0]

  def start_console(self):
    # Set up initial console environment
    console_env = {
      'ad': self._ad,
      'pprint': pprint.pprint,
    }

    # Start the services
    self._start_services(console_env)

    # Start the console
    console_banner = self._get_banner(self._ad.serial)
    code.interact(banner=console_banner, local=console_env)

    # Tear everything down
    self._ad.services.stop_all()

  def main(self, serial=None):
    try:
      self.load_device(serial)
    except Error as e:
      print('ERROR: %s' % e, file=sys.stderr)
      sys.exit(1)
    self.start_console()
