#!/usr/bin/env python3
#
# Copyright 2022 The Fuchsia Authors
#
# 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.

import copy
import shutil
import tempfile
import unittest

import antlion.controllers.relay_lib.fugu_remote as fugu_remote
from antlion.controllers.relay_lib.errors import RelayConfigError
from antlion.controllers.relay_lib.errors import RelayDeviceConnectionError
from antlion.controllers.relay_lib.generic_relay_device import GenericRelayDevice
from antlion.controllers.relay_lib.relay import Relay
from antlion.controllers.relay_lib.relay import RelayDict
from antlion.controllers.relay_lib.relay import RelayState
from antlion.controllers.relay_lib.relay import SynchronizeRelays
from antlion.controllers.relay_lib.relay_board import RelayBoard
from antlion.controllers.relay_lib.relay_device import RelayDevice
from antlion.controllers.relay_lib.relay_rig import RelayRig
from antlion.controllers.relay_lib.sain_smart_board import SainSmartBoard
from mock import patch


class MockBoard(RelayBoard):
    def __init__(self, config):
        self.relay_states = dict()
        self.relay_previous_states = dict()
        RelayBoard.__init__(self, config)

    def get_relay_position_list(self):
        return [0, 1]

    def get_relay_status(self, relay_position):
        if relay_position not in self.relay_states:
            self.relay_states[relay_position] = RelayState.NO
            self.relay_previous_states[relay_position] = RelayState.NO
        return self.relay_states[relay_position]

    def set(self, relay_position, state):
        self.relay_previous_states[relay_position] = self.get_relay_status(
            relay_position)
        self.relay_states[relay_position] = state
        return state


class ActsRelayTest(unittest.TestCase):
    def setUp(self):
        Relay.transition_wait_time = 0
        Relay.button_press_time = 0
        self.config = {
            'name': 'MockBoard',
            'relays': [{
                'name': 'Relay',
                'relay_pos': 0
            }]
        }
        self.board = MockBoard(self.config)
        self.relay = Relay(self.board, 'Relay')
        self.board.set(self.relay.position, RelayState.NO)

    def tearDown(self):
        Relay.transition_wait_time = .2
        Relay.button_press_time = .25

    def test_turn_on_from_off(self):
        self.board.set(self.relay.position, RelayState.NO)
        self.relay.set_nc()
        self.assertEqual(self.board.get_relay_status(self.relay.position),
                         RelayState.NC)

    def test_turn_on_from_on(self):
        self.board.set(self.relay.position, RelayState.NC)
        self.relay.set_nc()
        self.assertEqual(self.board.get_relay_status(self.relay.position),
                         RelayState.NC)

    def test_turn_off_from_on(self):
        self.board.set(self.relay.position, RelayState.NC)
        self.relay.set_no()
        self.assertEqual(self.board.get_relay_status(self.relay.position),
                         RelayState.NO)

    def test_turn_off_from_off(self):
        self.board.set(self.relay.position, RelayState.NO)
        self.relay.set_no()
        self.assertEqual(self.board.get_relay_status(self.relay.position),
                         RelayState.NO)

    def test_toggle_off_to_on(self):
        self.board.set(self.relay.position, RelayState.NO)
        self.relay.toggle()
        self.assertEqual(self.board.get_relay_status(self.relay.position),
                         RelayState.NC)

    def test_toggle_on_to_off(self):
        self.board.set(self.relay.position, RelayState.NC)
        self.relay.toggle()
        self.assertEqual(self.board.get_relay_status(self.relay.position),
                         RelayState.NO)

    def test_set_on(self):
        self.board.set(self.relay.position, RelayState.NO)
        self.relay.set(RelayState.NC)
        self.assertEqual(self.board.get_relay_status(self.relay.position),
                         RelayState.NC)

    def test_set_off(self):
        self.board.set(self.relay.position, RelayState.NC)
        self.relay.set(RelayState.NO)
        self.assertEqual(self.board.get_relay_status(self.relay.position),
                         RelayState.NO)

    def test_set_foo(self):
        with self.assertRaises(ValueError):
            self.relay.set('FOO')

    def test_set_nc_for(self):
        # Here we set twice so relay_previous_state will also be OFF
        self.board.set(self.relay.position, RelayState.NO)
        self.board.set(self.relay.position, RelayState.NO)

        self.relay.set_nc_for(0)

        self.assertEqual(self.board.get_relay_status(self.relay.position),
                         RelayState.NO)
        self.assertEqual(self.board.relay_previous_states[self.relay.position],
                         RelayState.NC)

    def test_set_no_for(self):
        # Here we set twice so relay_previous_state will also be OFF
        self.board.set(self.relay.position, RelayState.NC)
        self.board.set(self.relay.position, RelayState.NC)

        self.relay.set_no_for(0)

        self.assertEqual(self.board.get_relay_status(self.relay.position),
                         RelayState.NC)
        self.assertEqual(self.board.relay_previous_states[self.relay.position],
                         RelayState.NO)

    def test_get_status_on(self):
        self.board.set(self.relay.position, RelayState.NC)
        self.assertEqual(self.relay.get_status(), RelayState.NC)

    def test_get_status_off(self):
        self.board.set(self.relay.position, RelayState.NO)
        self.assertEqual(self.relay.get_status(), RelayState.NO)

    def test_clean_up_default_on(self):
        new_relay = Relay(self.board, 0)
        new_relay._original_state = RelayState.NO
        self.board.set(new_relay.position, RelayState.NO)
        new_relay.clean_up()

        self.assertEqual(self.board.get_relay_status(new_relay.position),
                         RelayState.NO)

    def test_clean_up_default_off(self):
        new_relay = Relay(self.board, 0)
        new_relay._original_state = RelayState.NO
        self.board.set(new_relay.position, RelayState.NC)
        new_relay.clean_up()

        self.assertEqual(self.board.get_relay_status(new_relay.position),
                         RelayState.NO)

    def test_clean_up_original_state_none(self):
        val = 'STAYS_THE_SAME'
        new_relay = Relay(self.board, 0)
        # _original_state is none by default
        # The line below sets the dict to an impossible value.
        self.board.set(new_relay.position, val)
        new_relay.clean_up()
        # If the impossible value is cleared, then the test should fail.
        self.assertEqual(self.board.get_relay_status(new_relay.position), val)


class ActsSainSmartBoardTest(unittest.TestCase):
    STATUS_MSG = ('<small><a href="{}"></a>'
                  '</small><a href="{}/{}TUX">{}TUX</a><p>')

    RELAY_ON_PAGE_CONTENTS = 'relay_on page'
    RELAY_OFF_PAGE_CONTENTS = 'relay_off page'

    def setUp(self):
        Relay.transition_wait_time = 0
        Relay.button_press_time = 0
        self.test_dir = 'file://' + tempfile.mkdtemp() + '/'

        # Creates the files used for testing
        self._set_status_page('0000000000000000')
        with open(self.test_dir[7:] + '00', 'w+') as file:
            file.write(self.RELAY_OFF_PAGE_CONTENTS)
        with open(self.test_dir[7:] + '01', 'w+') as file:
            file.write(self.RELAY_ON_PAGE_CONTENTS)

        self.config = ({
            'name':
            'SSBoard',
            'base_url':
            self.test_dir,
            'relays': [{
                'name': '0',
                'relay_pos': 0
            }, {
                'name': '1',
                'relay_pos': 1
            }, {
                'name': '2',
                'relay_pos': 7
            }]
        })
        self.ss_board = SainSmartBoard(self.config)
        self.r0 = Relay(self.ss_board, 0)
        self.r1 = Relay(self.ss_board, 1)
        self.r7 = Relay(self.ss_board, 7)

    def tearDown(self):
        shutil.rmtree(self.test_dir[7:])
        Relay.transition_wait_time = .2
        Relay.button_press_time = .25

    def test_get_url_code(self):
        result = self.ss_board._get_relay_url_code(self.r0.position,
                                                   RelayState.NO)
        self.assertEqual(result, '00')

        result = self.ss_board._get_relay_url_code(self.r0.position,
                                                   RelayState.NC)
        self.assertEqual(result, '01')

        result = self.ss_board._get_relay_url_code(self.r7.position,
                                                   RelayState.NO)
        self.assertEqual(result, '14')

        result = self.ss_board._get_relay_url_code(self.r7.position,
                                                   RelayState.NC)
        self.assertEqual(result, '15')

    def test_load_page_status(self):
        self._set_status_page('0000111100001111')
        result = self.ss_board._load_page(SainSmartBoard.HIDDEN_STATUS_PAGE)
        self.assertTrue(
            result.endswith(
                '0000111100001111TUX">0000111100001111TUX</a><p>'))

    def test_load_page_relay(self):
        result = self.ss_board._load_page('00')
        self.assertEqual(result, self.RELAY_OFF_PAGE_CONTENTS)

        result = self.ss_board._load_page('01')
        self.assertEqual(result, self.RELAY_ON_PAGE_CONTENTS)

    def test_load_page_no_connection(self):
        with self.assertRaises(RelayDeviceConnectionError):
            self.ss_board._load_page('**')

    def _set_status_page(self, status_16_chars):
        with open(self.test_dir[7:] + '99', 'w+') as status_file:
            status_file.write(
                self.STATUS_MSG.format(self.test_dir[:-1], self.test_dir[:-1],
                                       status_16_chars, status_16_chars))

    def _test_sync_status_dict(self, status_16_chars):
        self._set_status_page(status_16_chars)
        expected_dict = dict()

        for index, char in enumerate(status_16_chars):
            expected_dict[
                index] = RelayState.NC if char == '1' else RelayState.NO

        self.ss_board._sync_status_dict()
        self.assertDictEqual(expected_dict, self.ss_board.status_dict)

    def test_sync_status_dict(self):
        self._test_sync_status_dict('0000111100001111')
        self._test_sync_status_dict('0000000000000000')
        self._test_sync_status_dict('0101010101010101')
        self._test_sync_status_dict('1010101010101010')
        self._test_sync_status_dict('1111111111111111')

    def test_get_relay_status_status_dict_none(self):
        self._set_status_page('1111111111111111')
        self.ss_board.status_dict = None
        self.assertEqual(self.ss_board.get_relay_status(self.r0.position),
                         RelayState.NC)

    def test_get_relay_status_status_dict_on(self):
        self.r0.set(RelayState.NC)
        self.assertEqual(self.ss_board.get_relay_status(self.r0.position),
                         RelayState.NC)

    def test_get_relay_status_status_dict_off(self):
        self.r0.set(RelayState.NO)
        self.assertEqual(self.ss_board.get_relay_status(self.r0.position),
                         RelayState.NO)

    def test_set_on(self):
        patch_path = 'antlion.controllers.relay_lib.sain_smart_board.urlopen'
        with patch(patch_path) as urlopen:
            board = SainSmartBoard(self.config)
            board.status_dict = {}
            board.set(self.r0.position, RelayState.NC)
        urlopen.assert_called_once_with('%s%s' %
                                        (self.ss_board.base_url, '01'))

    def test_set_off(self):
        patch_path = 'antlion.controllers.relay_lib.sain_smart_board.urlopen'
        with patch(patch_path) as urlopen:
            board = SainSmartBoard(self.config)
            board.status_dict = {}
            board.set(self.r0.position, RelayState.NO)
        urlopen.assert_called_once_with('%s%s' %
                                        (self.ss_board.base_url, '00'))

    def test_connection_error_no_tux(self):
        default_status_msg = self.STATUS_MSG
        self.STATUS_MSG = self.STATUS_MSG.replace('TUX', '')
        try:
            self._set_status_page('1111111111111111')
            self.ss_board.get_relay_status(0)
        except RelayDeviceConnectionError:
            self.STATUS_MSG = default_status_msg
            return

        self.fail('Should have thrown an error without TUX appearing.')


class ActsRelayRigTest(unittest.TestCase):
    def setUp(self):
        Relay.transition_wait_time = 0
        Relay.button_press_time = 0
        self.config = {
            'boards': [{
                'type': 'SainSmartBoard',
                'name': 'ss_control',
                'base_url': 'http://192.168.1.4/30000/'
            }, {
                'type': 'SainSmartBoard',
                'name': 'ss_control_2',
                'base_url': 'http://192.168.1.4/30000/'
            }],
            'devices': [{
                'type': 'GenericRelayDevice',
                'name': 'device',
                'relays': {
                    'Relay00': 'ss_control/0',
                    'Relay10': 'ss_control/1'
                }
            }]
        }

    def tearDown(self):
        Relay.transition_wait_time = .2
        Relay.button_press_time = .25

    def test_init_relay_rig_missing_boards(self):
        flawed_config = copy.deepcopy(self.config)
        del flawed_config['boards']
        with self.assertRaises(RelayConfigError):
            RelayRig(flawed_config)

    def test_init_relay_rig_is_not_list(self):
        flawed_config = copy.deepcopy(self.config)
        flawed_config['boards'] = self.config['boards'][0]
        with self.assertRaises(RelayConfigError):
            RelayRig(flawed_config)

    def test_init_relay_rig_duplicate_board_names(self):
        flawed_config = copy.deepcopy(self.config)
        flawed_config['boards'][1]['name'] = (self.config['boards'][0]['name'])
        with self.assertRaises(RelayConfigError):
            RelayRigMock(flawed_config)

    def test_init_relay_rig_device_gets_relays(self):
        modded_config = copy.deepcopy(self.config)
        del modded_config['devices'][0]['relays']['Relay00']
        rig = RelayRigMock(modded_config)
        self.assertEqual(len(rig.relays), 4)
        self.assertEqual(len(rig.devices['device'].relays), 1)

        rig = RelayRigMock(self.config)
        self.assertEqual(len(rig.devices['device'].relays), 2)

    def test_init_relay_rig_correct_device_type(self):
        rig = RelayRigMock(self.config)
        self.assertEqual(len(rig.devices), 1)
        self.assertIsInstance(rig.devices['device'], GenericRelayDevice)

    def test_init_relay_rig_missing_devices_creates_generic_device(self):
        modded_config = copy.deepcopy(self.config)
        del modded_config['devices']
        rig = RelayRigMock(modded_config)
        self.assertEqual(len(rig.devices), 1)
        self.assertIsInstance(rig.devices['device'], GenericRelayDevice)
        self.assertDictEqual(rig.devices['device'].relays, rig.relays)


class RelayRigMock(RelayRig):
    """A RelayRig that substitutes the MockBoard for any board."""

    _board_constructors = {
        'SainSmartBoard': lambda x: MockBoard(x),
        'FuguMockBoard': lambda x: FuguMockBoard(x)
    }

    def __init__(self, config=None):
        if not config:
            config = {
                "boards": [{
                    'name': 'MockBoard',
                    'type': 'SainSmartBoard'
                }]
            }

        RelayRig.__init__(self, config)


class ActsGenericRelayDeviceTest(unittest.TestCase):
    def setUp(self):
        Relay.transition_wait_time = 0
        Relay.button_press_time = 0
        self.board_config = {'name': 'MockBoard', 'type': 'SainSmartBoard'}

        self.board = MockBoard(self.board_config)
        self.r0 = self.board.relays[0]
        self.r1 = self.board.relays[1]

        self.device_config = {
            'name': 'MockDevice',
            'relays': {
                'r0': 'MockBoard/0',
                'r1': 'MockBoard/1'
            }
        }
        config = {
            'boards': [self.board_config],
            'devices': [self.device_config]
        }
        self.rig = RelayRigMock(config)
        self.rig.boards['MockBoard'] = self.board
        self.rig.relays[self.r0.relay_id] = self.r0
        self.rig.relays[self.r1.relay_id] = self.r1

    def tearDown(self):
        Relay.transition_wait_time = .2
        Relay.button_press_time = .25

    def test_setup_single_relay(self):
        self.r0.set(RelayState.NC)
        self.r1.set(RelayState.NC)

        modified_config = copy.deepcopy(self.device_config)
        del modified_config['relays']['r1']

        grd = GenericRelayDevice(modified_config, self.rig)
        grd.setup()

        self.assertEqual(self.r0.get_status(), RelayState.NO)
        self.assertEqual(self.r1.get_status(), RelayState.NC)

    def test_setup_multiple_relays(self):
        self.board.set(self.r0.position, RelayState.NC)
        self.board.set(self.r1.position, RelayState.NC)

        grd = GenericRelayDevice(self.device_config, self.rig)
        grd.setup()

        self.assertEqual(self.r0.get_status(), RelayState.NO)
        self.assertEqual(self.r1.get_status(), RelayState.NO)

    def test_cleanup_single_relay(self):
        self.test_setup_single_relay()

    def test_cleanup_multiple_relays(self):
        self.test_setup_multiple_relays()

    def change_state(self, begin_state, call, end_state, previous_state=None):
        self.board.set(self.r0.position, begin_state)
        grd = GenericRelayDevice(self.device_config, self.rig)
        call(grd)
        self.assertEqual(self.r0.get_status(), end_state)
        if previous_state:
            self.assertEqual(
                self.board.relay_previous_states[self.r0.position],
                previous_state)

    def test_press_while_no(self):
        self.change_state(RelayState.NO, lambda x: x.press('r0'),
                          RelayState.NO, RelayState.NC)

    def test_press_while_nc(self):
        self.change_state(RelayState.NC, lambda x: x.press('r0'),
                          RelayState.NO, RelayState.NC)

    def test_hold_down_while_no(self):
        self.change_state(RelayState.NO, lambda x: x.hold_down('r0'),
                          RelayState.NC)

    def test_hold_down_while_nc(self):
        self.change_state(RelayState.NC, lambda x: x.hold_down('r0'),
                          RelayState.NC)

    def test_release_while_nc(self):
        self.change_state(RelayState.NC, lambda x: x.release('r0'),
                          RelayState.NO)


class ActsRelayDeviceTest(unittest.TestCase):
    def setUp(self):
        Relay.transition_wait_time = 0
        Relay.button_press_time = 0

        self.board_config = {
            'name': 'MockBoard',
            'relays': [{
                'id': 0,
                'relay_pos': 0
            }, {
                'id': 1,
                'relay_pos': 1
            }]
        }

        self.board = MockBoard(self.board_config)
        self.r0 = Relay(self.board, 0)
        self.r1 = Relay(self.board, 1)
        self.board.set(self.r0.position, RelayState.NO)
        self.board.set(self.r1.position, RelayState.NO)

        self.rig = RelayRigMock()
        self.rig.boards['MockBoard'] = self.board
        self.rig.relays[self.r0.relay_id] = self.r0
        self.rig.relays[self.r1.relay_id] = self.r1

        self.device_config = {
            "type": "GenericRelayDevice",
            "name": "device",
            "relays": {
                'r0': 'MockBoard/0',
                'r1': 'MockBoard/1'
            }
        }

    def tearDown(self):
        Relay.transition_wait_time = .2
        Relay.button_press_time = .25

    def test_init_raise_on_name_missing(self):
        flawed_config = copy.deepcopy(self.device_config)
        del flawed_config['name']
        with self.assertRaises(RelayConfigError):
            RelayDevice(flawed_config, self.rig)

    def test_init_raise_on_name_wrong_type(self):
        flawed_config = copy.deepcopy(self.device_config)
        flawed_config['name'] = {}
        with self.assertRaises(RelayConfigError):
            RelayDevice(flawed_config, self.rig)

    def test_init_raise_on_relays_missing(self):
        flawed_config = copy.deepcopy(self.device_config)
        del flawed_config['relays']
        with self.assertRaises(RelayConfigError):
            RelayDevice(flawed_config, self.rig)

    def test_init_raise_on_relays_wrong_type(self):
        flawed_config = copy.deepcopy(self.device_config)
        flawed_config['relays'] = str
        with self.assertRaises(RelayConfigError):
            RelayDevice(flawed_config, self.rig)

    def test_init_raise_on_relays_is_empty(self):
        flawed_config = copy.deepcopy(self.device_config)
        flawed_config['relays'] = []
        with self.assertRaises(RelayConfigError):
            RelayDevice(flawed_config, self.rig)

    def test_init_raise_on_relays_are_dicts_without_names(self):
        flawed_config = copy.deepcopy(self.device_config)
        flawed_config['relays'] = [{'id': 0}, {'id': 1}]
        with self.assertRaises(RelayConfigError):
            RelayDevice(flawed_config, self.rig)

    def test_init_raise_on_relays_are_dicts_without_ids(self):
        flawed_config = copy.deepcopy(self.device_config)
        flawed_config['relays'] = [{'name': 'r0'}, {'name': 'r1'}]
        with self.assertRaises(RelayConfigError):
            RelayDevice(flawed_config, self.rig)

    def test_init_pass_relays_have_ids_and_names(self):
        RelayDevice(self.device_config, self.rig)


class TestRelayRigParser(unittest.TestCase):
    def setUp(self):
        Relay.transition_wait_time = 0
        Relay.button_press_time = 0
        self.board_config = {
            'name': 'MockBoard',
            'relays': [{
                'id': 'r0',
                'relay_pos': 0
            }, {
                'id': 'r1',
                'relay_pos': 1
            }]
        }
        self.r0 = self.board_config['relays'][0]
        self.r1 = self.board_config['relays'][1]
        self.board = MockBoard(self.board_config)

    def tearDown(self):
        Relay.transition_wait_time = .2
        Relay.button_press_time = .25

    def test_create_relay_board_raise_on_missing_type(self):
        with self.assertRaises(RelayConfigError):
            RelayRigMock().create_relay_board(self.board_config)

    def test_create_relay_board_valid_config(self):
        config = copy.deepcopy(self.board_config)
        config['type'] = 'SainSmartBoard'
        RelayRigMock().create_relay_board(config)

    def test_create_relay_board_raise_on_type_not_found(self):
        flawed_config = copy.deepcopy(self.board_config)
        flawed_config['type'] = 'NonExistentBoard'
        with self.assertRaises(RelayConfigError):
            RelayRigMock().create_relay_board(flawed_config)

    def test_create_relay_device_create_generic_on_missing_type(self):
        rig = RelayRigMock()
        rig.relays['r0'] = self.r0
        rig.relays['r1'] = self.r1
        config = {
            'name': 'name',
            'relays': {
                'r0': 'MockBoard/0',
                'r1': 'MockBoard/1'
            }
        }
        device = rig.create_relay_device(config)
        self.assertIsInstance(device, GenericRelayDevice)

    def test_create_relay_device_config_with_type(self):
        rig = RelayRigMock()
        rig.relays['r0'] = self.r0
        rig.relays['r1'] = self.r1
        config = {
            'type': 'GenericRelayDevice',
            'name': '.',
            'relays': {
                'r0': 'MockBoard/0',
                'r1': 'MockBoard/1'
            }
        }
        device = rig.create_relay_device(config)
        self.assertIsInstance(device, GenericRelayDevice)

    def test_create_relay_device_raise_on_type_not_found(self):
        rig = RelayRigMock()
        rig.relays['r0'] = self.r0
        rig.relays['r1'] = self.r1
        config = {
            'type':
            'SomeInvalidType',
            'name':
            '.',
            'relays': [{
                'name': 'r0',
                'pos': 'MockBoard/0'
            }, {
                'name': 'r1',
                'pos': 'MockBoard/1'
            }]
        }
        with self.assertRaises(RelayConfigError):
            rig.create_relay_device(config)


class TestSynchronizeRelays(unittest.TestCase):
    def test_synchronize_relays(self):
        Relay.transition_wait_time = .1
        with SynchronizeRelays():
            self.assertEqual(Relay.transition_wait_time, 0)
        self.assertEqual(Relay.transition_wait_time, .1)


class FuguMockBoard(MockBoard):
    def get_relay_position_list(self):
        return range(4)


class TestFuguRemote(unittest.TestCase):
    def setUp(self):
        Relay.transition_wait_time = 0
        self.mock_rig = RelayRigMock(
            {"boards": [{
                'name': 'MockBoard',
                'type': 'FuguMockBoard'
            }]})
        self.mock_board = self.mock_rig.boards['MockBoard']
        self.fugu_config = {
            'type': 'FuguRemote',
            'name': 'UniqueDeviceName',
            'mac_address': '00:00:00:00:00:00',
            'relays': {
                'Power': 'MockBoard/0',
                fugu_remote.Buttons.BACK.value: 'MockBoard/1',
                fugu_remote.Buttons.HOME.value: 'MockBoard/2',
                fugu_remote.Buttons.PLAY_PAUSE.value: 'MockBoard/3'
            }
        }
        Relay.button_press_time = 0

    def tearDown(self):
        Relay.button_press_time = .25
        Relay.transition_wait_time = .2

    def test_config_missing_button(self):
        """FuguRemote __init__ should throw an error if a relay is missing."""
        flawed_config = copy.deepcopy(self.fugu_config)
        del flawed_config['relays']['Power']
        del flawed_config['relays'][fugu_remote.Buttons.BACK.value]
        with self.assertRaises(RelayConfigError):
            fugu_remote.FuguRemote(flawed_config, self.mock_rig)

    def test_config_missing_mac_address(self):
        """FuguRemote __init__ should throw an error without a mac address."""
        flawed_config = copy.deepcopy(self.fugu_config)
        del flawed_config['mac_address']
        with self.assertRaises(RelayConfigError):
            fugu_remote.FuguRemote(flawed_config, self.mock_rig)

    def test_config_no_issues(self):
        """FuguRemote __init__ should not throw errors for a correct config."""
        fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)

    def test_power_nc_after_setup(self):
        """Power should be NORMALLY_CLOSED after calling setup if it exists."""
        fugu = fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)
        fugu.setup()
        self.assertEqual(self.mock_board.get_relay_status(0), RelayState.NC)

    def press_button_success(self, relay_position):
        self.assertEqual(self.mock_board.relay_states[relay_position],
                         RelayState.NO)
        self.assertEqual(self.mock_board.relay_previous_states[relay_position],
                         RelayState.NC)

    def test_press_play_pause(self):
        fugu = fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)
        fugu.press_play_pause()
        self.press_button_success(3)

    def test_press_back(self):
        fugu = fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)
        fugu.press_back()
        self.press_button_success(1)

    def test_press_home(self):
        fugu = fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)
        fugu.press_home()
        self.press_button_success(2)

    def test_enter_pairing_mode(self):
        fugu = fugu_remote.FuguRemote(self.fugu_config, self.mock_rig)
        fugu_remote.PAIRING_MODE_WAIT_TIME = 0
        fugu.enter_pairing_mode()
        self.press_button_success(2)
        self.press_button_success(1)


class TestRelayDict(unittest.TestCase):
    def test_init(self):
        mock_device = object()
        blank_dict = dict()
        relay_dict = RelayDict(mock_device, blank_dict)
        self.assertEqual(relay_dict._store, blank_dict)
        self.assertEqual(relay_dict.relay_device, mock_device)

    def test_get_item_valid_key(self):
        mock_device = object()
        blank_dict = {'key': 'value'}
        relay_dict = RelayDict(mock_device, blank_dict)
        self.assertEqual(relay_dict['key'], 'value')

    def test_get_item_invalid_key(self):
        # Create an object with a single attribute 'name'
        mock_device = type('', (object, ), {'name': 'name'})()
        blank_dict = {'key': 'value'}
        relay_dict = RelayDict(mock_device, blank_dict)
        with self.assertRaises(RelayConfigError):
            value = relay_dict['not_key']

    def test_iter(self):
        mock_device = type('', (object, ), {'name': 'name'})()
        data_dict = {'a': '1', 'b': '2', 'c': '3'}
        relay_dict = RelayDict(mock_device, data_dict)

        rd_set = set()
        for key in relay_dict:
            rd_set.add(key)
        dd_set = set()
        for key in data_dict:
            dd_set.add(key)

        self.assertSetEqual(rd_set, dd_set)


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