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

from builtins import str

import json
import mock
import socket
from future.tests.base import unittest

from mobly.controllers.android_device_lib import jsonrpc_client_base
from tests.lib import jsonrpc_client_test_base


class FakeRpcClient(jsonrpc_client_base.JsonRpcClientBase):

  def __init__(self):
    super().__init__(app_name='FakeRpcClient', ad=mock.Mock())


class JsonRpcClientBaseTest(jsonrpc_client_test_base.JsonRpcClientTestBase):
  """Unit tests for mobly.controllers.android_device_lib.jsonrpc_client_base.
  """

  @mock.patch('socket.create_connection')
  def test_open_timeout_io_error(self, mock_create_connection):
    """Test socket timeout with io error

    Test that if the net socket gives an io error, then the client
    will eventually exit with an IOError.
    """
    mock_create_connection.side_effect = IOError()
    with self.assertRaises(IOError):
      client = FakeRpcClient()
      client.connect()

  @mock.patch('socket.create_connection')
  def test_connect_timeout(self, mock_create_connection):
    """Test socket timeout

    Test that a timeout exception will be raised if the socket gives a
    timeout.
    """
    mock_create_connection.side_effect = socket.timeout
    with self.assertRaises(socket.timeout):
      client = FakeRpcClient()
      client.connect()

  @mock.patch('socket.create_connection')
  def test_handshake_error(self, mock_create_connection):
    """Test error in jsonrpc handshake

    Test that if there is an error in the jsonrpc handshake then a protocol
    error will be raised.
    """
    self.setup_mock_socket_file(mock_create_connection, resp=None)
    client = FakeRpcClient()
    with self.assertRaisesRegex(
        jsonrpc_client_base.ProtocolError,
        jsonrpc_client_base.ProtocolError.NO_RESPONSE_FROM_HANDSHAKE):
      client.connect()

  @mock.patch('socket.create_connection')
  def test_connect_handshake(self, mock_create_connection):
    """Test client handshake

    Test that at the end of a handshake with no errors the client object
    has the correct parameters.
    """
    self.setup_mock_socket_file(mock_create_connection)
    client = FakeRpcClient()
    client.connect()
    self.assertEqual(client.uid, 1)

  @mock.patch('socket.create_connection')
  def test_connect_handshake_unknown_status(self, mock_create_connection):
    """Test handshake with unknown status response

    Test that when the handshake is given an unknown status then the client
    will not be given a uid.
    """
    self.setup_mock_socket_file(mock_create_connection,
                                resp=self.MOCK_RESP_UNKNOWN_STATUS)
    client = FakeRpcClient()
    client.connect()
    self.assertEqual(client.uid, jsonrpc_client_base.UNKNOWN_UID)

  @mock.patch('socket.create_connection')
  def test_rpc_error_response(self, mock_create_connection):
    """Test rpc that is given an error response

    Test that when an rpc receives a response with an error will raised
    an api error.
    """
    fake_file = self.setup_mock_socket_file(mock_create_connection)

    client = FakeRpcClient()
    client.connect()

    fake_file.resp = self.MOCK_RESP_WITH_ERROR

    with self.assertRaisesRegex(jsonrpc_client_base.ApiError, '1'):
      client.some_rpc(1, 2, 3)

  @mock.patch('socket.create_connection')
  def test_rpc_callback_response(self, mock_create_connection):
    """Test rpc that is given a callback response.

    Test that when an rpc receives a callback response, a callback object is
    created correctly.
    """
    fake_file = self.setup_mock_socket_file(mock_create_connection)

    client = FakeRpcClient()
    client.connect()

    fake_file.resp = self.MOCK_RESP_WITH_CALLBACK
    client._event_client = mock.Mock()

    callback = client.some_rpc(1, 2, 3)
    self.assertEqual(callback.ret_value, 123)
    self.assertEqual(callback._id, '1-0')

  @mock.patch('socket.create_connection')
  def test_rpc_id_mismatch(self, mock_create_connection):
    """Test rpc that returns a different id than expected

    Test that if an rpc returns with an id that is different than what
    is expected will give a protocl error.
    """
    fake_file = self.setup_mock_socket_file(mock_create_connection)

    client = FakeRpcClient()
    client.connect()

    fake_file.resp = (self.MOCK_RESP_TEMPLATE % 52).encode('utf8')

    with self.assertRaisesRegex(
        jsonrpc_client_base.ProtocolError,
        jsonrpc_client_base.ProtocolError.MISMATCHED_API_ID):
      client.some_rpc(1, 2, 3)

  @mock.patch('socket.create_connection')
  def test_rpc_no_response(self, mock_create_connection):
    """Test rpc that does not get a response

    Test that when an rpc does not get a response it throws a protocol
    error.
    """
    fake_file = self.setup_mock_socket_file(mock_create_connection)

    client = FakeRpcClient()
    client.connect()

    fake_file.resp = None

    with self.assertRaisesRegex(
        jsonrpc_client_base.ProtocolError,
        jsonrpc_client_base.ProtocolError.NO_RESPONSE_FROM_SERVER):
      client.some_rpc(1, 2, 3)

  @mock.patch('socket.create_connection')
  def test_rpc_send_to_socket(self, mock_create_connection):
    """Test rpc sending and recieving

    Tests that when an rpc is sent and received the corrent data
    is used.
    """
    fake_file = self.setup_mock_socket_file(mock_create_connection)

    client = FakeRpcClient()
    client.connect()

    result = client.some_rpc(1, 2, 3)
    self.assertEqual(result, 123)

    expected = {'id': 0, 'method': 'some_rpc', 'params': [1, 2, 3]}
    actual = json.loads(fake_file.last_write.decode('utf-8'))

    self.assertEqual(expected, actual)

  @mock.patch('socket.create_connection')
  def test_rpc_send_to_socket_without_callback(self, mock_create_connection):
    """Test rpc sending and recieving with Rpc protocol before callback was
    added to the resp message.

    Logic is the same as test_rpc_send_to_socket.
    """
    fake_file = self.setup_mock_socket_file(
        mock_create_connection, resp=self.MOCK_RESP_WITHOUT_CALLBACK)

    client = FakeRpcClient()
    client.connect()

    result = client.some_rpc(1, 2, 3)
    self.assertEqual(result, 123)

    expected = {'id': 0, 'method': 'some_rpc', 'params': [1, 2, 3]}
    actual = json.loads(fake_file.last_write.decode('utf-8'))

    self.assertEqual(expected, actual)

  @mock.patch('socket.create_connection')
  def test_rpc_call_increment_counter(self, mock_create_connection):
    """Test rpc counter

    Test that with each rpc call the counter is incremented by 1.
    """
    fake_file = self.setup_mock_socket_file(mock_create_connection)

    client = FakeRpcClient()
    client.connect()

    for i in range(0, 10):
      fake_file.resp = (self.MOCK_RESP_TEMPLATE % i).encode('utf-8')
      client.some_rpc()

    self.assertEqual(next(client._counter), 10)

  @mock.patch('socket.create_connection')
  def test_rpc_verbose_logging_with_long_string(self, mock_create_connection):
    """Test rpc response fully write into DEBUG level log."""
    fake_file = self.setup_mock_socket_file(mock_create_connection)
    testing_rpc_response = self.generate_rpc_response(4000)
    fake_file.resp = testing_rpc_response

    client = FakeRpcClient()
    client.connect()

    response = client._client_receive()
    self.assertEqual(response, testing_rpc_response)

    client.log.debug.assert_called_with('Snippet received: %s',
                                        testing_rpc_response)

  @mock.patch('socket.create_connection')
  def test_rpc_truncated_logging_short_response(self, mock_create_connection):
    """Test rpc response will full logged when length is short."""
    fake_file = self.setup_mock_socket_file(mock_create_connection)
    testing_rpc_response = self.generate_rpc_response(
        int(jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH / 2))
    fake_file.resp = testing_rpc_response

    client = FakeRpcClient()
    client.connect()

    client.set_snippet_client_verbose_logging(False)
    response = client._client_receive()

    self.assertEqual(response, testing_rpc_response)
    client.log.debug.assert_called_with('Snippet received: %s',
                                        testing_rpc_response)

  @mock.patch('socket.create_connection')
  def test_rpc_truncated_logging_fit_size_response(self,
                                                   mock_create_connection):
    """Test rpc response will full logged when length is equal to threshold.
    """
    fake_file = self.setup_mock_socket_file(mock_create_connection)
    testing_rpc_response = self.generate_rpc_response(
        jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH)
    fake_file.resp = testing_rpc_response

    client = FakeRpcClient()
    client.connect()

    client.set_snippet_client_verbose_logging(False)
    response = client._client_receive()

    self.assertEqual(response, testing_rpc_response)
    client.log.debug.assert_called_with('Snippet received: %s',
                                        testing_rpc_response)

  @mock.patch('socket.create_connection')
  def test_rpc_truncated_logging_long_response(self, mock_create_connection):
    """Test rpc response truncated with given length in DEBUG level log."""
    fake_file = self.setup_mock_socket_file(mock_create_connection)
    resp_len = jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH * 40
    testing_rpc_response = self.generate_rpc_response(resp_len)
    fake_file.resp = testing_rpc_response

    client = FakeRpcClient()
    client.connect()

    client.set_snippet_client_verbose_logging(False)
    response = client._client_receive()

    self.assertEqual(response, testing_rpc_response)
    # DEBUG level log should truncated by given length.
    client.log.debug.assert_called_with(
        'Snippet received: %s... %d chars are truncated',
        testing_rpc_response[:jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH],
        resp_len - jsonrpc_client_base._MAX_RPC_RESP_LOGGING_LENGTH)


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