import contextlib
import io
import glob
import os
import unittest
from unittest.mock import Mock, patch

os.environ.setdefault('REDIS_STREAMS_ENABLED', 'false')
os.environ.setdefault('DATABASE_URL', 'postgresql://fixture:fixture@localhost:1/fixture')


class ConnectionLoggingTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        assert not glob.glob('/dev/nvidia*'), 'GPU-free validation required'
    def test_success_keeps_ping_without_url(self):
        from app import metadata_storage as module
        client = Mock()
        library = Mock(from_url=Mock(return_value=client))
        output = io.StringIO()
        url = 'redis://test-user:private-password@localhost:1/0'
        with patch.object(module, 'REDIS_STREAMS_ENABLED', True), patch.object(module, 'redis_lib', library), contextlib.redirect_stdout(output):
            publisher = module.RedisMetadataPublisher(url)
        self.assertIs(publisher._client, client)
        client.ping.assert_called_once()
        library.from_url.assert_called_once_with(url, decode_responses=True)
        self.assertEqual(output.getvalue(), '[RedisPublisher] Connected\n')

    def test_failure_removes_message_and_unknown_type(self):
        from app import metadata_storage as module
        for name, expected in [('AuthenticationError', 'AuthenticationError'), ('private-password', 'RedisError')]:
            error = type(name, (Exception,), {})('private-password endpoint-detail')
            library = Mock(from_url=Mock(side_effect=error))
            output = io.StringIO()
            with patch.object(module, 'REDIS_STREAMS_ENABLED', True), patch.object(module, 'redis_lib', library), contextlib.redirect_stdout(output):
                publisher = module.RedisMetadataPublisher('private-url')
            self.assertIsNone(publisher._client)
            self.assertIn(expected, output.getvalue())
            self.assertNotIn('private-', output.getvalue())
            self.assertNotIn('endpoint-detail', output.getvalue())

    def test_disabled_does_not_connect(self):
        from app import metadata_storage as module
        library = Mock()
        with patch.object(module, 'REDIS_STREAMS_ENABLED', False), patch.object(module, 'redis_lib', library):
            self.assertIsNone(module.RedisMetadataPublisher('unused')._client)
        library.from_url.assert_not_called()
