#!/usr/bin/env python3
"""Test the files module."""

# Standard imports
import unittest
import os
import sys


# Try to create a working PYTHONPATH
EXEC_DIR = os.path.dirname(os.path.realpath(__file__))
ROOT_DIR = os.path.abspath(os.path.join(
    os.path.abspath(os.path.join(EXEC_DIR, os.pardir)), os.pardir))
if EXEC_DIR.endswith('/pattoo-shared/tests/test_pattoo_shared') is True:
    # We need to prepend the path in case PattooShared has been installed
    # elsewhere on the system using PIP. This could corrupt expected results
    sys.path.insert(0, ROOT_DIR)
else:
    print('''\
This script is not installed in the "pattoo-shared/tests/test_pattoo_shared" \
directory. Please fix.''')
    sys.exit(2)

# Pattoo imports
from pattoo_shared import configuration
from pattoo_shared.variables import PollingTarget
from tests.libraries.configuration import UnittestConfig


class TestConfig(unittest.TestCase):
    """Checks all functions and methods."""

    #########################################################################
    # General object setup
    #########################################################################

    config = configuration.Config()

    def test___init__(self):
        """Testing function __init__."""
        pass

    def test_api_listen_address(self):
        """Testing function api_listen_address."""
        # Initialize key values
        expected = '0.0.0.0'

        # Test
        result = self.config.api_listen_address()
        self.assertEqual(result, expected)

    def test_polling_interval(self):
        """Testing function polling_interval."""
        # Initialize key values
        expected = 20

        # Test
        result = self.config.polling_interval()
        self.assertEqual(result, expected)

    def test_api_ip_address(self):
        """Testing function api_ip_address."""
        # Initialize key values
        expected = '127.0.0.1'

        # Test
        result = self.config.api_ip_address()
        self.assertEqual(result, expected)

    def test_api_ip_bind_port(self):
        """Testing function api_ip_bind_port."""
        # Initialize key values
        expected = 6060

        # Test
        result = self.config.api_ip_bind_port()
        self.assertEqual(result, expected)

    def test_api_uses_https(self):
        """Testing function api_uses_https."""
        # Initialize key values
        expected = False

        # Test
        result = self.config.api_uses_https()
        self.assertEqual(result, expected)

    def test_api_uri(self):
        """Testing function api_uri."""
        # Initialize key values
        expected = '/pattoo/api/v1/agent/receive'

        # Test
        result = self.config.api_uri()
        self.assertEqual(result, expected)

    def test_api_server_url(self):
        """Testing function api_server_url."""
        # Initialize key values
        expected = 'http://127.0.0.1:6060/pattoo/api/v1/agent/receive/123'
        agent_id = 123

        # Test
        result = self.config.api_server_url(agent_id)
        self.assertEqual(result, expected)

    def test_daemon_directory(self):
        """Testing function daemon_directory."""
        # Nothing should happen. Directory exists in testing.
        _ = self.config.daemon_directory()

    def test_log_directory(self):
        """Testing function log_directory."""
        # Nothing should happen. Directory exists in testing.
        _ = self.config.log_directory()

    def test_log_file(self):
        """Testing function log_file."""
        # Initialize key values
        expected = '{1}{0}pattoo.log'.format(
            os.sep, self.config.log_directory())

        # Test
        result = self.config.log_file()
        self.assertEqual(result, expected)

    def test_log_file_api(self):
        """Testing function log_file_api."""
        # Initialize key values
        expected = '{1}{0}pattoo-api.log'.format(
            os.sep, self.config.log_directory())

        # Test
        result = self.config.log_file_api()
        self.assertEqual(result, expected)

    def test_log_level(self):
        """Testing function log_level."""
        # Initialize key values
        expected = 'debug'

        # Test
        result = self.config.log_level()
        self.assertEqual(result, expected)

    def test_log_file_daemon(self):
        """Testing function log_file_daemon."""
        # Initialize key values
        expected = '{1}{0}pattoo-daemon.log'.format(
            os.sep, self.config.log_directory())

        # Test
        result = self.config.log_file_daemon()
        self.assertEqual(result, expected)

    def test_cache_directory(self):
        """Testing function cache_directory."""
        # Nothing should happen. Directory exists in testing.
        _ = self.config.cache_directory()

    def test_agent_cache_directory(self):
        """Testing function agent_cache_directory."""
        # Initialize key values
        agent_id = 123
        expected = '{1}{0}{2}'.format(
            os.sep, self.config.cache_directory(), agent_id)

        # Test
        result = self.config.agent_cache_directory(agent_id)
        self.assertEqual(result, expected)

    def test__polling_targets(self):
        """Testing function _polling_targets."""
        # Initialize key values
        oids = ['.1.3.6.1.2.1.2.2.1.10', '.1.3.6.1.2.1.2.2.1.16']
        data = [
            {'address': '.1.3.6.1.2.1.2.2.1.10',
             'multiplier': 8},
            {'address': '.1.3.6.1.2.1.2.2.1.16',
             'multiplier': 8}]

        # Test with good data
        result = self.config._polling_targets(data)
        self.assertTrue(isinstance(result, list))
        self.assertTrue(bool(result))
        for index, value in enumerate(result):
            self.assertTrue(isinstance(value, PollingTarget))
            self.assertEqual(value.address, oids[index])
            self.assertEqual(value.multiplier, 8)


class TestBasicFunctions(unittest.TestCase):
    """Checks all functions and methods."""

    #########################################################################
    # General object setup
    #########################################################################

    def test_search(self):
        """Testing function search."""
        # Initialize key variables
        data = {
            1: {
                11: '11',
                12: '12'
            },
            2: {
                21: '21',
                22: '22'
            },
            3: {
                31: '31',
                32: '32'
            },
            4: {
                41: '41',
                42: '42'
            }
        }

        # Test OK value
        expected = '11'
        result = configuration.search(1, 11, data)
        self.assertEqual(result, expected)

        # Test all values
        for key, key_dict in data.items():
            for sub_key, expected in key_dict.items():
                result = configuration.search(key, sub_key, data)
                self.assertEqual(result, expected)

        # Test bad values
        with self.assertRaises(SystemExit):
            _ = configuration.search('1111111', 11, data)

        # Test bad values
        _ = configuration.search('1111111', 11, data, die=False)


if __name__ == '__main__':
    # Make sure the environment is OK to run unittests
    UnittestConfig().create()

    # Do the unit test
    unittest.main()
