#!/usr/bin/env python3
#
#   Copyright 2016 - The Android Open Source Project
#
#   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 acts.controllers.relay_lib.fugu_remote as fugu_remote
from acts.controllers.relay_lib.errors import RelayConfigError
from acts.controllers.relay_lib.errors import RelayDeviceConnectionError
from acts.controllers.relay_lib.generic_relay_device import GenericRelayDevice
from acts.controllers.relay_lib.relay import Relay
from acts.controllers.relay_lib.relay import RelayDict
from acts.controllers.relay_lib.relay import RelayState
from acts.controllers.relay_lib.relay import SynchronizeRelays
from acts.controllers.relay_lib.relay_board import RelayBoard
from acts.controllers.relay_lib.relay_device import RelayDevice
from acts.controllers.relay_lib.relay_rig import RelayRig
from acts.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 = 'acts.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 = 'acts.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)
        pass

    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()
