import unittest
import importlib.util
import os
import sys
from unittest.mock import patch
import tempfile
from preseem.netmeta_config_loader import load_config, DuplicateKeyError
from mock import patch


class TestLoadConfig(unittest.TestCase):

    def setUp(self):
        self.invalid_yaml = """
        # This is a random comment
        snmp:
            community: Abc Xyz
            credentials:
                - username: user123
                  password: pass123
                  role: ap
                  username: NEWuser123
                  password: NEWpass234
                  role: NEWap
                            """

        self.valid_yaml = """
        snmp:
            community: abcdef
            credentials:
                - username: user123
                  password: pass123
                - username: user123
                  password: pass234
                - username: user234
                  password: pass567
                            """

        # Create temporary testfile for invalid config
        self.invalid_config_file = tempfile.NamedTemporaryFile(delete=False,
                                                               suffix=".yaml")
        self.invalid_config_file.write(self.invalid_yaml.encode('utf-8'))
        self.invalid_config_file_path = self.invalid_config_file.name
        self.invalid_config_file.close()

        # Create temporary testfile for valid config
        self.valid_config_file = tempfile.NamedTemporaryFile(delete=False,
                                                             suffix=".yaml")
        self.valid_config_file.write(self.valid_yaml.encode('utf-8'))
        self.valid_config_file_path = self.valid_config_file.name
        self.valid_config_file.close()

    def tearDown(self):
        # Clean up the temporary files after tests
        if os.path.exists(self.invalid_config_file.name):
            os.remove(self.invalid_config_file.name)
        if os.path.exists(self.valid_config_file.name):
            os.remove(self.valid_config_file.name)

    def test_valid_config(self):
        config = load_config(self.valid_config_file_path)
        self.assertIsInstance(config, dict)  # Valid

        # Assert all fields
        expected_config = {
            "snmp": {
                "community":
                "abcdef",
                "credentials": [
                    {
                        "username": "user123",
                        "password": "pass123"
                    },
                    {
                        "username": "user123",
                        "password": "pass234"
                    },
                    {
                        "username": "user234",
                        "password": "pass567"
                    },
                ]
            }
        }
        self.assertEqual(config, expected_config)

    @patch("preseem.netmeta_config_loader.logging")
    def test_invalid_config(self, mock_logger):
        config = load_config(self.invalid_config_file_path)

        # Check if the ambiguous YAML error message was logged
        logged_errors = [
            call[1][0] for call in mock_logger.method_calls if call[0] == "error"
        ]
        self.assertTrue(
            any("Ambiguous YAML detected" in error for error in logged_errors),
            "Expected error message not found in logged errors.")

    def test_missing_file(self):
        with self.assertRaises(RuntimeError) as context:
            load_config("random_file.yaml")
        self.assertIn("config file not found", str(context.exception))


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