import collections
import unittest
import src.services.monitor.resources_monitor as rm
from collections import namedtuple
from elasticsearch import Elasticsearch
from unittest.mock import patch


class ResourcesMonitorTest(unittest.TestCase):
    TUPLE_FOR_PARSE = namedtuple('Person', 'first_name last_name zip_code')
    T1 = TUPLE_FOR_PARSE('Joe', 'Smith', '93002')
    T1_PARSED = {'first_name': 'Joe', 'last_name': 'Smith', 'zip_code': '93002'}
    CLIENT = Elasticsearch("http://10.6.71.62:9200")

    def test_send_to_elasticsearch(self):
        RESPONSE = rm.send_to_elasticsearch(rm._get_sensors_battery(), self.CLIENT, "index_battery")
        self.assertIsNotNone(RESPONSE)

    def test_parse_tuple(self):
        parsed_tuple = rm._parse_tuple(self.T1)
        self.assertEqual(self.T1_PARSED, parsed_tuple)

    def test_get_cpu_times(self):
        cpu_times = rm._get_cpu_times()
        for i in cpu_times.values():
            self.assertTrue(type(i) == str or int)

    def test_get_cpu_stats(self):
        cpu_stats = rm._get_cpu_stats()
        for i in cpu_stats.values():
            self.assertTrue(type(i) == str or int)

    def test_get_virtual_memory(self):
        virtual_memory = rm._get_virtual_memory()
        for i in virtual_memory.values():
            self.assertTrue(type(i) == str or int)

    def test_get_swap_memory(self):
        swap_memory = rm._get_swap_memory()
        for i in swap_memory.values():
            self.assertTrue(type(i) == str or int)

    def test_get_sensors_battery(self):
        sensors_battery = rm._get_sensors_battery()
        for i in sensors_battery.values():
            self.assertTrue(type(i) == str or int)

    def test_get_disk_usage(self):
        disk_usage = rm._get_disk_usage()
        for i in disk_usage.values():
            self.assertTrue(type(i) == str or int)

    def test_get_disk_io_counters_outer(self):
        disk_io_counters = rm._get_disk_io_counters()
        for i in disk_io_counters.values():
            self.assertTrue(isinstance(i, type({})))

    def test_get_disk_io_counters_inner(self):
        disk_io_counters = rm._get_disk_io_counters()
        for i in disk_io_counters.values():
            for j in i:
                self.assertTrue(type(j) == str or int)

    def test_get_bytes_tx_and_rx_outer(self):
        bytes_tx_and_rx = rm._get_bytes_tx_and_rx()
        for i in bytes_tx_and_rx.values():
            self.assertTrue(isinstance(i, type({})))

    def test_get_bytes_tx_and_rx_inner(self):
        bytes_tx_and_rx = rm._get_bytes_tx_and_rx()
        for i in bytes_tx_and_rx.values():
            for j in i:
                self.assertTrue(type(j) == str or int)

    def test_get_net_stats_outer(self):
        net_stats = rm._get_net_stats()
        for i in net_stats.values():
            self.assertTrue(isinstance(i, type({})))

    def test_get_net_stats_inner(self):
        net_stats = rm._get_net_stats()
        for i in net_stats.values():
            for j in i:
                self.assertTrue(type(j) == str or int)

    def test_get_sensor_temperature_layer1_checker(self):
        sensor_temperature = rm._get_sensor_temperature()
        for i in sensor_temperature.values():
            self.assertTrue(isinstance(i, type([])))

    def test_get_sensor_temperature_layer2_checker(self):
        sensor_temperature = rm._get_sensor_temperature()
        for i in sensor_temperature.values():
            for j in i:
                self.assertTrue(isinstance(j, type({})))

    def test_get_sensor_temperature_layer3_checker(self):
        sensor_temperature = rm._get_sensor_temperature()
        for i in sensor_temperature.values():
            for j in i:
                for k in j:
                    self.assertTrue(type(k) == str or int)

    def test_get_sensor_temperature_hardware(self):
        Temp = collections.namedtuple("Temp", "label current high critical")
        hw_sensors = {'acpitz': [Temp('', 47.0, 103.0, 103.0)],
                      'asus': [Temp('', 47.0, None, None)],
                      'coretemp': [Temp('Physical id 0', 52.0, 100.0, 100.0),
                                   Temp('Core 0', 45.0, 100.0, 100.0),
                                   Temp('Core 1', 52.0, 100.0, 100.0),
                                   Temp('Core 2', 45.0, 100.0, 100.0),
                                   Temp('Core 3', 47.0, 100.0, 100.0)]}
        with patch("psutil.sensors_temperatures", return_value=hw_sensors):
            sensor_temperature = rm._get_sensor_temperature()
            self.assertFalse(len(sensor_temperature) == 0)

    def test_get_all_resources_data(self):
        data = rm._get_all_resources_data()
        self.assertIsInstance(data, dict)


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