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

from builtins import str
from builtins import bytes

import mock
import sys
from future.tests.base import unittest

from mobly.controllers.android_device_lib import adb
from mobly.controllers.android_device_lib import jsonrpc_client_base
from mobly.controllers.android_device_lib import snippet_client
from tests.lib import jsonrpc_client_test_base
from tests.lib import mock_android_device

MOCK_PACKAGE_NAME = 'some.package.name'
MOCK_MISSING_PACKAGE_NAME = 'not.installed'
JSONRPC_BASE_CLASS = 'mobly.controllers.android_device_lib.jsonrpc_client_base.JsonRpcClientBase'
MOCK_USER_ID = 0


def get_print_function_name():
  """Gets the name of the print function for mocking.

  Returns:
    A str representing the print function to mock.
  """
  if sys.version_info >= (3, 0):
    return 'builtins.print'
  else:
    return '__builtin__.print'


class SnippetClientTest(jsonrpc_client_test_base.JsonRpcClientTestBase):
  """Unit tests for mobly.controllers.android_device_lib.snippet_client.
  """

  def test_check_app_installed_normal(self):
    sc = self._make_client()
    sc._check_app_installed()

  def test_check_app_installed_fail_app_not_installed(self):
    sc = self._make_client(mock_android_device.MockAdbProxy())
    expected_msg = '.* %s is not installed.' % MOCK_PACKAGE_NAME
    with self.assertRaisesRegex(snippet_client.AppStartPreCheckError,
                  expected_msg):
      sc._check_app_installed()

  def test_check_app_installed_fail_not_instrumented(self):
    sc = self._make_client(
      mock_android_device.MockAdbProxy(
        installed_packages=[MOCK_PACKAGE_NAME]))
    expected_msg = ('.* %s is installed, but it is not instrumented.' %
            MOCK_PACKAGE_NAME)
    with self.assertRaisesRegex(snippet_client.AppStartPreCheckError,
                  expected_msg):
      sc._check_app_installed()

  def test_check_app_installed_fail_target_not_installed(self):
    sc = self._make_client(
      mock_android_device.MockAdbProxy(instrumented_packages=[(
        MOCK_PACKAGE_NAME,
        snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
        MOCK_MISSING_PACKAGE_NAME)]))
    expected_msg = ('.* Instrumentation target %s is not installed.' %
            MOCK_MISSING_PACKAGE_NAME)
    with self.assertRaisesRegex(snippet_client.AppStartPreCheckError,
                  expected_msg):
      sc._check_app_installed()

  @mock.patch('socket.create_connection')
  def test_snippet_start(self, mock_create_connection):
    self.setup_mock_socket_file(mock_create_connection)
    client = self._make_client()
    client.connect()
    result = client.testSnippetCall()
    self.assertEqual(123, result)

  @mock.patch('socket.create_connection')
  def test_snippet_start_event_client(self, mock_create_connection):
    fake_file = self.setup_mock_socket_file(mock_create_connection)
    client = self._make_client()
    client.host_port = 123  # normally picked by start_app_and_connect
    client.connect()
    fake_file.resp = self.MOCK_RESP_WITH_CALLBACK
    callback = client.testSnippetCall()
    self.assertEqual(123, callback.ret_value)
    self.assertEqual('1-0', callback._id)

    # Check to make sure the event client is using the same port as the
    # main client.
    self.assertEqual(123, callback._event_client.host_port)

    fake_file.resp = self.MOCK_RESP_WITH_ERROR
    with self.assertRaisesRegex(jsonrpc_client_base.ApiError, '1'):
      callback.getAll('eventName')

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.get_available_host_port')
  def test_snippet_restore_event_client(self, mock_get_port,
                      mock_create_connection):
    mock_get_port.return_value = 789
    fake_file = self.setup_mock_socket_file(mock_create_connection)
    client = self._make_client()
    client.host_port = 123  # normally picked by start_app_and_connect
    client.device_port = 456
    client.connect()
    fake_file.resp = self.MOCK_RESP_WITH_CALLBACK
    callback = client.testSnippetCall()

    # before reconnect, clients use previously selected ports
    self.assertEqual(123, client.host_port)
    self.assertEqual(456, client.device_port)
    self.assertEqual(123, callback._event_client.host_port)
    self.assertEqual(456, callback._event_client.device_port)

    # after reconnect, if host port specified, clients use specified port
    client.restore_app_connection(port=321)
    self.assertEqual(321, client.host_port)
    self.assertEqual(456, client.device_port)
    self.assertEqual(321, callback._event_client.host_port)
    self.assertEqual(456, callback._event_client.device_port)

    # after reconnect, if host port not specified, clients use selected
    # available port
    client.restore_app_connection()
    self.assertEqual(789, client.host_port)
    self.assertEqual(456, client.device_port)
    self.assertEqual(789, callback._event_client.host_port)
    self.assertEqual(456, callback._event_client.device_port)

    # if unable to reconnect for any reason, a
    # jsonrpc_client_base.AppRestoreConnectionError is raised.
    mock_create_connection.side_effect = IOError('socket timed out')
    with self.assertRaisesRegex(
        jsonrpc_client_base.AppRestoreConnectionError,
      ('Failed to restore app connection for %s at host port %s, '
       'device port %s') % (MOCK_PACKAGE_NAME, 789, 456)):
      client.restore_app_connection()

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.get_available_host_port')
  def test_snippet_start_app_and_connect(self, mock_get_port,
                       mock_start_standing_subprocess,
                       mock_create_connection):
    self.setup_mock_socket_file(mock_create_connection)
    self._setup_mock_instrumentation_cmd(
      mock_start_standing_subprocess,
      resp_lines=[
        b'SNIPPET START, PROTOCOL 1 0\n',
        b'SNIPPET SERVING, PORT 123\n',
      ])
    client = self._make_client()
    client.start_app_and_connect()
    self.assertEqual(123, client.device_port)
    self.assertTrue(client.is_alive)

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.stop_standing_subprocess')
  def test_snippet_stop_app(self, mock_stop_standing_subprocess,
                mock_create_connection):
    adb_proxy = mock.MagicMock()
    adb_proxy.shell.return_value = b'OK (0 tests)'
    client = self._make_client(adb_proxy)
    client.stop_app()
    self.assertFalse(client.is_alive)

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'SnippetClient.disconnect')
  def test_snippet_stop_app_raises(self, mock_disconnect,
                   mock_create_connection):
    mock_disconnect.side_effect = Exception('ha')
    adb_proxy = mock.MagicMock()
    adb_proxy.shell.return_value = b'OK (0 tests)'
    client = self._make_client(adb_proxy)
    client.host_port = 1
    with self.assertRaisesRegex(Exception, 'ha'):
      client.stop_app()
    adb_proxy.forward.assert_called_once_with(['--remove', 'tcp:1'])

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.get_available_host_port')
  @mock.patch(
    'mobly.controllers.android_device_lib.snippet_client.SnippetClient.'
    'disable_hidden_api_blacklist')
  @mock.patch(
    'mobly.controllers.android_device_lib.snippet_client.SnippetClient.'
    'stop_app')
  def test_start_app_and_connect_precheck_fail(
      self, mock_stop, mock_precheck, mock_get_port,
      mock_start_standing_subprocess, mock_create_connection):
    self.setup_mock_socket_file(mock_create_connection)
    self._setup_mock_instrumentation_cmd(
      mock_start_standing_subprocess,
      resp_lines=[
        b'SNIPPET START, PROTOCOL 1 0\n',
        b'SNIPPET SERVING, PORT 123\n',
      ])
    client = self._make_client()
    mock_precheck.side_effect = snippet_client.AppStartPreCheckError(
      client.ad, 'ha')
    with self.assertRaisesRegex(snippet_client.AppStartPreCheckError,
                  'ha'):
      client.start_app_and_connect()
    mock_stop.assert_not_called()
    self.assertFalse(client.is_alive)

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.get_available_host_port')
  @mock.patch(
    'mobly.controllers.android_device_lib.snippet_client.SnippetClient._start_app_and_connect'
  )
  @mock.patch(
    'mobly.controllers.android_device_lib.snippet_client.SnippetClient.stop_app'
  )
  def test_start_app_and_connect_generic_error(
      self, mock_stop, mock_start, mock_get_port,
      mock_start_standing_subprocess, mock_create_connection):
    self.setup_mock_socket_file(mock_create_connection)
    self._setup_mock_instrumentation_cmd(
      mock_start_standing_subprocess,
      resp_lines=[
        b'SNIPPET START, PROTOCOL 1 0\n',
        b'SNIPPET SERVING, PORT 123\n',
      ])
    client = self._make_client()
    mock_start.side_effect = Exception('ha')
    with self.assertRaisesRegex(Exception, 'ha'):
      client.start_app_and_connect()
    mock_stop.assert_called_once_with()
    self.assertFalse(client.is_alive)

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.get_available_host_port')
  @mock.patch(
    'mobly.controllers.android_device_lib.snippet_client.SnippetClient._start_app_and_connect'
  )
  @mock.patch(
    'mobly.controllers.android_device_lib.snippet_client.SnippetClient.stop_app'
  )
  def test_start_app_and_connect_fail_stop_also_fail(
      self, mock_stop, mock_start, mock_get_port,
      mock_start_standing_subprocess, mock_create_connection):
    self.setup_mock_socket_file(mock_create_connection)
    self._setup_mock_instrumentation_cmd(
      mock_start_standing_subprocess,
      resp_lines=[
        b'SNIPPET START, PROTOCOL 1 0\n',
        b'SNIPPET SERVING, PORT 123\n',
      ])
    client = self._make_client()
    mock_start.side_effect = Exception('Some error')
    mock_stop.side_effect = Exception('Another error')
    with self.assertRaisesRegex(Exception, 'Some error'):
      client.start_app_and_connect()
    mock_stop.assert_called_once_with()
    self.assertFalse(client.is_alive)

  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'SnippetClient._do_start_app')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'SnippetClient._check_app_installed')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'SnippetClient._read_protocol_line')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'SnippetClient.connect')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.get_available_host_port')
  def test_snippet_start_on_sdk_21(self, mock_get_port, mock_connect,
                   mock_read_protocol_line,
                   mock_check_app_installed,
                   mock_do_start_app):
    """Check that `--user` is not added to start command on SDK < 24."""

    def _mocked_shell(arg):
      if 'setsid' in arg:
        raise adb.AdbError('cmd', 'stdout', 'stderr', 'ret_code')
      else:
        return b'nohup'

    mock_get_port.return_value = 123
    mock_read_protocol_line.side_effect = [
      'SNIPPET START, PROTOCOL 1 234',
      'SNIPPET SERVING, PORT 1234',
      'SNIPPET START, PROTOCOL 1 234',
      'SNIPPET SERVING, PORT 1234',
      'SNIPPET START, PROTOCOL 1 234',
      'SNIPPET SERVING, PORT 1234',
    ]

    # Test 'setsid' exists
    client = self._make_client()
    client._ad.build_info['build_version_sdk'] = 21
    client._adb.shell = mock.Mock(return_value=b'setsid')
    client.start_app_and_connect()
    cmd_setsid = '%s am instrument  -w -e action start %s/%s' % (
      snippet_client._SETSID_COMMAND, MOCK_PACKAGE_NAME,
      snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
    mock_do_start_app.assert_has_calls([mock.call(cmd_setsid)])

  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'SnippetClient._do_start_app')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'SnippetClient._check_app_installed')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'SnippetClient._read_protocol_line')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'SnippetClient.connect')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.get_available_host_port')
  def test_snippet_start_app_and_connect_persistent_session(
      self, mock_get_port, mock_connect, mock_read_protocol_line,
      mock_check_app_installed, mock_do_start_app):
    def _mocked_shell(arg):
      if 'setsid' in arg:
        raise adb.AdbError('cmd', 'stdout', 'stderr', 'ret_code')
      else:
        return b'nohup'

    mock_get_port.return_value = 123
    mock_read_protocol_line.side_effect = [
      'SNIPPET START, PROTOCOL 1 234',
      'SNIPPET SERVING, PORT 1234',
      'SNIPPET START, PROTOCOL 1 234',
      'SNIPPET SERVING, PORT 1234',
      'SNIPPET START, PROTOCOL 1 234',
      'SNIPPET SERVING, PORT 1234',
    ]

    # Test 'setsid' exists
    client = self._make_client()
    client._adb.shell = mock.Mock(return_value=b'setsid')
    client.start_app_and_connect()
    cmd_setsid = '%s am instrument --user %s -w -e action start %s/%s' % (
      snippet_client._SETSID_COMMAND, MOCK_USER_ID, MOCK_PACKAGE_NAME,
      snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
    mock_do_start_app.assert_has_calls([mock.call(cmd_setsid)])

    # Test 'setsid' does not exist, but 'nohup' exsits
    client = self._make_client()
    client._adb.shell = _mocked_shell
    client.start_app_and_connect()
    cmd_nohup = '%s am instrument --user %s -w -e action start %s/%s' % (
      snippet_client._NOHUP_COMMAND, MOCK_USER_ID, MOCK_PACKAGE_NAME,
      snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
    mock_do_start_app.assert_has_calls(
      [mock.call(cmd_setsid),
       mock.call(cmd_nohup)])

    # Test both 'setsid' and 'nohup' do not exist
    client._adb.shell = mock.Mock(
      side_effect=adb.AdbError('cmd', 'stdout', 'stderr', 'ret_code'))
    client = self._make_client()
    client.start_app_and_connect()
    cmd_not_persist = ' am instrument --user %s -w -e action start %s/%s' % (
      MOCK_USER_ID, MOCK_PACKAGE_NAME,
      snippet_client._INSTRUMENTATION_RUNNER_PACKAGE)
    mock_do_start_app.assert_has_calls([
      mock.call(cmd_setsid),
      mock.call(cmd_nohup),
      mock.call(cmd_not_persist)
    ])

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.get_available_host_port')
  def test_snippet_start_app_crash(self, mock_get_port,
                   mock_start_standing_subprocess,
                   mock_create_connection):
    mock_get_port.return_value = 456
    self.setup_mock_socket_file(mock_create_connection)
    self._setup_mock_instrumentation_cmd(
      mock_start_standing_subprocess,
      resp_lines=[
        b'INSTRUMENTATION_RESULT: shortMsg=Process crashed.\n'
      ])
    client = self._make_client()
    with self.assertRaisesRegex(
        snippet_client.ProtocolVersionError,
        'INSTRUMENTATION_RESULT: shortMsg=Process crashed.'):
      client.start_app_and_connect()

  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.get_available_host_port')
  def test_snippet_start_app_and_connect_unknown_protocol(
      self, mock_get_port, mock_start_standing_subprocess):
    mock_get_port.return_value = 789
    self._setup_mock_instrumentation_cmd(
      mock_start_standing_subprocess,
      resp_lines=[b'SNIPPET START, PROTOCOL 99 0\n'])
    client = self._make_client()
    with self.assertRaisesRegex(snippet_client.ProtocolVersionError,
                  'SNIPPET START, PROTOCOL 99 0'):
      client.start_app_and_connect()

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.get_available_host_port')
  def test_snippet_start_app_and_connect_header_junk(
      self, mock_get_port, mock_start_standing_subprocess,
      mock_create_connection):
    self.setup_mock_socket_file(mock_create_connection)
    self._setup_mock_instrumentation_cmd(
      mock_start_standing_subprocess,
      resp_lines=[
        b'This is some header junk\n',
        b'Some phones print arbitrary output\n',
        b'SNIPPET START, PROTOCOL 1 0\n',
        b'Maybe in the middle too\n',
        b'SNIPPET SERVING, PORT 123\n',
      ])
    client = self._make_client()
    client.start_app_and_connect()
    self.assertEqual(123, client.device_port)

  @mock.patch('socket.create_connection')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.start_standing_subprocess')
  @mock.patch('mobly.controllers.android_device_lib.snippet_client.'
        'utils.get_available_host_port')
  def test_snippet_start_app_and_connect_no_valid_line(
      self, mock_get_port, mock_start_standing_subprocess,
      mock_create_connection):
    mock_get_port.return_value = 456
    self.setup_mock_socket_file(mock_create_connection)
    self._setup_mock_instrumentation_cmd(
      mock_start_standing_subprocess,
      resp_lines=[
        b'This is some header junk\n',
        b'Some phones print arbitrary output\n',
        b'',  # readline uses '' to mark EOF
      ])
    client = self._make_client()
    with self.assertRaisesRegex(jsonrpc_client_base.AppStartError,
                  'Unexpected EOF waiting for app to start'):
      client.start_app_and_connect()

  @mock.patch(get_print_function_name())
  def test_help_rpc_when_printing_by_default(self, mock_print):
    client = self._make_client()
    mock_rpc = mock.MagicMock()
    client._rpc = mock_rpc

    result = client.help()
    mock_rpc.assert_called_once_with('help')
    self.assertEqual(None, result)
    mock_print.assert_called_once_with(mock_rpc.return_value)

  @mock.patch(get_print_function_name())
  def test_help_rpc_when_not_printing(self, mock_print):
    client = self._make_client()
    mock_rpc = mock.MagicMock()
    client._rpc = mock_rpc

    result = client.help(print_output=False)
    mock_rpc.assert_called_once_with('help')
    self.assertEqual(mock_rpc.return_value, result)
    mock_print.assert_not_called()

  def _make_client(self, adb_proxy=None):
    adb_proxy = adb_proxy or mock_android_device.MockAdbProxy(
      instrumented_packages=[(
        MOCK_PACKAGE_NAME,
        snippet_client._INSTRUMENTATION_RUNNER_PACKAGE,
        MOCK_PACKAGE_NAME)])
    ad = mock.Mock()
    ad.adb = adb_proxy
    ad.adb.current_user_id = MOCK_USER_ID
    ad.build_info = {
      'build_version_codename':
      ad.adb.getprop('ro.build.version.codename'),
      'build_version_sdk': ad.adb.getprop('ro.build.version.sdk'),
    }
    return snippet_client.SnippetClient(package=MOCK_PACKAGE_NAME, ad=ad)

  def _setup_mock_instrumentation_cmd(self, mock_start_standing_subprocess,
                    resp_lines):
    mock_proc = mock_start_standing_subprocess()
    mock_proc.stdout.readline.side_effect = resp_lines


if __name__ == "__main__":
  unittest.main()
