# Copyright 2022 Google LLC
#
# 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.

"""Unit tests for gdm_manager."""
from parameterized import parameterized
import unittest
from unittest import mock

import gazoo_device
from gazoo_device import errors as gdm_errors

from local_agent import errors as agent_errors
from local_agent.translation_layer import gdm_manager


####################### Fake data for unit test #############################
_FAKE_DEVICE_TYPE = 'fake-device-type'
_FAKE_DEVICE_ID = 'fake-device-id'
_FAKE_DEVICE_ID2 = 'fake-device-id2'
_FAKE_DETECTION_RESULT = {
    'efr32-3453': {
        'persistent': {'device_type': 'efr32', 'serial_number': '000440173453'},
        },
    'nrf52840-1234': {
        'persistent': {'device_type': 'nrf52849', 'serial_number': '1234'},
        },
}
_FAKE_ERROR_MSG = 'error'
##############################################################################


class GdmManagerTest(unittest.TestCase):
    """Unit tests for gdm_manager module."""

    def setUp(self):
        super().setUp()
        self.mgr = gdm_manager.GdmManager(mock.Mock())

    @parameterized.expand([(True, ['pw_rpc_common']), (False, [])])
    @mock.patch.object(gazoo_device.Manager, 'create_and_close_device')
    @mock.patch.object(gazoo_device.Manager, 'is_device_connected')
    @mock.patch.object(gazoo_device.Manager, 'get_devices')
    @mock.patch.object(gazoo_device.Manager, 'detect')
    def test_detect_devices(
        self,
        has_capabilities_result,
        expected_capability,
        mock_detect,
        mock_get_devices,
        mock_is_connect,
        mock_create_and_close_device):
        """Verifies detect_devices on success."""
        mock_get_devices.return_value = _FAKE_DETECTION_RESULT
        mock_is_connect.side_effect = [True, False]
        fake_device = mock.Mock()
        mock_create_and_close_device.return_value.iter.return_value = fake_device
        mock_create_and_close_device.return_value.__enter__.return_value = fake_device
        fake_device.matter_endpoints.get_supported_endpoints_and_clusters.return_value = {}
        fake_device.has_capabilities.return_value = has_capabilities_result

        device_statuses = self.mgr.detect_devices()

        expected_statuses = [
            {
                'deviceId': 'efr32-3453',
                'serialNumber': '000440173453',
                'deviceType': 'efr32',
                'capabilities': expected_capability,
            },
        ]
        self.assertEqual(expected_statuses, device_statuses)
        mock_detect.assert_called_once_with(
            force_overwrite=True, log_directory='/tmp')

    @mock.patch.object(gazoo_device.Manager, 'create_device')
    def test_create_devices_on_success(self, mock_create):
        """Verifies create_devices on success."""
        identifiers = [_FAKE_DEVICE_ID, _FAKE_DEVICE_ID2]
        self.mgr.create_devices(identifiers)
        mock_create.assert_called_with(
            identifier=_FAKE_DEVICE_ID2, log_directory=None)
        self.assertEqual(2, mock_create.call_count)

    @mock.patch.object(gazoo_device.Manager, 'is_device_connected')
    def test_check_device_connected_on_success(
        self, mock_is_device_connected):
        """Verifies check_device_connected succeeds when device connected."""
        mock_is_device_connected.return_value = True
        self.mgr.check_device_connected(_FAKE_DEVICE_ID)
        self.assertEqual(1, mock_is_device_connected.call_count)

    @mock.patch.object(gazoo_device.Manager, 'is_device_connected')
    def test_check_device_connected_raises_when_disconnected(
        self, mock_is_device_connected):
        """Verifies check_device_connected raises when device disconnected."""
        mock_is_device_connected.return_value = False
        with self.assertRaises(agent_errors.DeviceNotConnectedError):
            self.mgr.check_device_connected(_FAKE_DEVICE_ID)
        self.assertEqual(1, mock_is_device_connected.call_count)

    @mock.patch.object(gazoo_device.Manager, 'is_device_connected')
    def test_check_device_connected_raises_unexpected_error(
        self, mock_is_device_connected):
        """
        Verifies check_device_connected raises when device operation has error.
        """
        mock_is_device_connected.side_effect = (
            gdm_errors.DeviceError(_FAKE_ERROR_MSG))
        with self.assertRaisesRegex(gdm_errors.DeviceError, _FAKE_ERROR_MSG):
            self.mgr.check_device_connected(_FAKE_DEVICE_ID)
        self.assertEqual(1, mock_is_device_connected.call_count)

    @mock.patch.object(gazoo_device.Manager, 'get_open_device')
    @mock.patch.object(gazoo_device.Manager, 'get_open_device_names')
    def test_get_device_instance_on_success(
        self, mock_get_open_device_names, mock_get_open_device):
        """Verifies get_device_instance on success."""
        mock_get_open_device_names.return_value = [_FAKE_DEVICE_ID]
        self.mgr.get_device_instance(_FAKE_DEVICE_ID)
        self.assertEqual(1, mock_get_open_device_names.call_count)
        mock_get_open_device.assert_called_once_with(_FAKE_DEVICE_ID)

    @mock.patch.object(gazoo_device.Manager, 'get_open_device_names')
    def test_get_device_instance_failure_because_device_not_open(
        self, mock_get_open_device_names):
        """Verifies get_device_instance on failure."""
        mock_get_open_device_names.return_value = []
        error_msg = f'{_FAKE_DEVICE_ID} is not open'
        with self.assertRaisesRegex(agent_errors.DeviceNotOpenError, error_msg):
            self.mgr.get_device_instance(_FAKE_DEVICE_ID)

    @mock.patch.object(gazoo_device.Manager, 'get_open_device')
    @mock.patch.object(gazoo_device.Manager, 'get_open_device_names')
    def test_get_device_type_on_success(
        self, mock_get_names, mock_get_device):
        """Verifies _get_device_type on success."""
        mock_get_names.return_value = {_FAKE_DEVICE_ID,}
        mock_get_device.return_value.device_type = _FAKE_DEVICE_TYPE
        dut_type = self.mgr.get_device_type(_FAKE_DEVICE_ID)
        self.assertEqual(_FAKE_DEVICE_TYPE, dut_type)
        self.assertEqual(1, mock_get_names.call_count)
        self.assertEqual(1, mock_get_device.call_count)

    @mock.patch.object(gazoo_device.Manager, 'get_open_device_names')
    def test_get_device_type_on_failure_not_open(self, mock_get_names):
        """Verifies _get_device_type on failure not open."""
        mock_get_names.return_value = []
        error_msg = f'{_FAKE_DEVICE_ID} is not open'
        with self.assertRaisesRegex(agent_errors.DeviceNotOpenError, error_msg):
            self.mgr.get_device_type(_FAKE_DEVICE_ID)

    @mock.patch.object(gazoo_device.Manager, 'close_open_devices')
    def test_close_open_devices_on_success(self, mock_close_open_devices):
        """Verifies close_open_devices on success."""
        self.mgr.close_open_devices()
        self.assertEqual(1, mock_close_open_devices.call_count)
