"""
Tests for the main TUI application.

This module contains unit tests for the HostsManagerApp class,
validating application behavior, navigation, and user interactions.
"""

from unittest.mock import Mock, patch


from hosts.tui.app import HostsManagerApp
from hosts.core.models import HostEntry, HostsFile
from hosts.core.parser import HostsParser
from hosts.core.config import Config


class TestHostsManagerApp:
    """Test cases for the HostsManagerApp class."""

    def test_app_initialization(self):
        """Test application initialization."""
        with patch("hosts.tui.app.HostsParser"), patch("hosts.tui.app.Config"):
            app = HostsManagerApp()

            assert app.title == "/etc/hosts Manager"
            assert app.sub_title == ""  # Now set by update_status
            assert app.edit_mode is False
            assert app.selected_entry_index == 0
            assert app.sort_column == ""
            assert app.sort_ascending is True

    def test_app_compose_method_exists(self):
        """Test that app has compose method."""
        with patch("hosts.tui.app.HostsParser"), patch("hosts.tui.app.Config"):
            app = HostsManagerApp()

            # Test that compose method exists and is callable
            assert hasattr(app, "compose")
            assert callable(app.compose)

    def test_load_hosts_file_success(self):
        """Test successful hosts file loading."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        # Create test hosts file
        test_hosts = HostsFile()
        test_entry = HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
        test_hosts.add_entry(test_entry)

        mock_parser.parse.return_value = test_hosts
        mock_parser.get_file_info.return_value = {
            "path": "/etc/hosts",
            "exists": True,
            "size": 100,
        }

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.populate_entries_table = Mock()
            app.update_entry_details = Mock()
            app.set_timer = Mock()

            app.load_hosts_file()

            # Verify hosts file was loaded
            assert len(app.hosts_file.entries) == 1
            assert app.hosts_file.entries[0].ip_address == "127.0.0.1"
            mock_parser.parse.assert_called_once()

    def test_load_hosts_file_not_found(self):
        """Test handling of missing hosts file."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)
        mock_parser.parse.side_effect = FileNotFoundError("Hosts file not found")

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.update_status = Mock()

            app.load_hosts_file()

            # Should handle error gracefully
            app.update_status.assert_called_with(
                "❌ Error loading hosts file: Hosts file not found"
            )

    def test_load_hosts_file_permission_error(self):
        """Test handling of permission denied error."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)
        mock_parser.parse.side_effect = PermissionError("Permission denied")

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.update_status = Mock()

            app.load_hosts_file()

            # Should handle error gracefully
            app.update_status.assert_called_with(
                "❌ Error loading hosts file: Permission denied"
            )

    def test_populate_entries_table_logic(self):
        """Test populating DataTable logic without UI dependencies."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)
        mock_config.should_show_default_entries.return_value = True
        mock_config.is_default_entry.return_value = False

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Mock the query_one method to return a mock table
            mock_table = Mock()
            app.query_one = Mock(return_value=mock_table)

            # Add test entries
            app.hosts_file = HostsFile()
            active_entry = HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
            inactive_entry = HostEntry(
                ip_address="192.168.1.1", hostnames=["router"], is_active=False
            )
            app.hosts_file.add_entry(active_entry)
            app.hosts_file.add_entry(inactive_entry)

            app.populate_entries_table()

            # Verify table methods were called
            mock_table.clear.assert_called_once_with(columns=True)
            mock_table.add_columns.assert_called_once()
            assert mock_table.add_row.call_count == 2  # Two entries added

    def test_update_entry_details_with_entry(self):
        """Test updating entry details pane."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)
        mock_config.should_show_default_entries.return_value = True

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Mock the query_one method to return disabled input widgets
            mock_details_display = Mock()
            mock_edit_form = Mock()
            mock_ip_input = Mock()
            mock_hostname_input = Mock()
            mock_comment_input = Mock()
            mock_active_checkbox = Mock()

            def mock_query_one(selector, widget_type=None):
                if selector == "#entry-details-display":
                    return mock_details_display
                elif selector == "#entry-edit-form":
                    return mock_edit_form
                elif selector == "#details-ip-input":
                    return mock_ip_input
                elif selector == "#details-hostname-input":
                    return mock_hostname_input
                elif selector == "#details-comment-input":
                    return mock_comment_input
                elif selector == "#details-active-checkbox":
                    return mock_active_checkbox
                return Mock()

            app.query_one = mock_query_one

            # Add test entry
            app.hosts_file = HostsFile()
            test_entry = HostEntry(
                ip_address="127.0.0.1",
                hostnames=["localhost", "local"],
                comment="Test comment",
            )
            app.hosts_file.add_entry(test_entry)
            app.selected_entry_index = 0

            app.update_entry_details()

            # Verify input widgets were updated with entry data
            mock_details_display.remove_class.assert_called_with("hidden")
            mock_edit_form.add_class.assert_called_with("hidden")
            assert mock_ip_input.value == "127.0.0.1"
            assert mock_hostname_input.value == "localhost, local"
            assert mock_comment_input.value == "Test comment"
            assert mock_active_checkbox.value

    def test_update_entry_details_no_entries(self):
        """Test updating entry details with no entries."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Mock the query_one method to return disabled input widgets
            mock_details_display = Mock()
            mock_edit_form = Mock()
            mock_ip_input = Mock()
            mock_hostname_input = Mock()
            mock_comment_input = Mock()
            mock_active_checkbox = Mock()

            def mock_query_one(selector, widget_type=None):
                if selector == "#entry-details-display":
                    return mock_details_display
                elif selector == "#entry-edit-form":
                    return mock_edit_form
                elif selector == "#details-ip-input":
                    return mock_ip_input
                elif selector == "#details-hostname-input":
                    return mock_hostname_input
                elif selector == "#details-comment-input":
                    return mock_comment_input
                elif selector == "#details-active-checkbox":
                    return mock_active_checkbox
                return Mock()

            app.query_one = mock_query_one
            app.hosts_file = HostsFile()

            app.update_entry_details()

            # Verify widgets show empty state placeholders
            mock_details_display.remove_class.assert_called_with("hidden")
            mock_edit_form.add_class.assert_called_with("hidden")
            assert mock_ip_input.value == ""
            assert mock_ip_input.placeholder == "No entries loaded"
            assert mock_hostname_input.value == ""
            assert mock_hostname_input.placeholder == "No entries loaded"
            assert mock_comment_input.value == ""
            assert mock_comment_input.placeholder == "No entries loaded"
            assert not mock_active_checkbox.value

    def test_update_status_default(self):
        """Test status bar update with default information."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)
        mock_parser.get_file_info.return_value = {
            "path": "/etc/hosts",
            "exists": True,
            "size": 100,
        }

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Mock the query_one method to avoid UI dependencies
            mock_footer = Mock()
            app.query_one = Mock(return_value=mock_footer)

            # Add test entries
            app.hosts_file = HostsFile()
            app.hosts_file.add_entry(
                HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
            )
            app.hosts_file.add_entry(
                HostEntry(
                    ip_address="192.168.1.1", hostnames=["router"], is_active=False
                )
            )

            app.update_status()

            # Verify footer status was updated
            mock_footer.set_status.assert_called_once()
            status_call = mock_footer.set_status.call_args[0][0]
            assert "Read-only" in status_call
            assert "2 entries" in status_call
            assert "1 active" in status_call

    def test_update_status_custom_message(self):
        """Test status bar update with custom message."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Mock set_timer and query_one to avoid event loop and UI issues
            app.set_timer = Mock()
            mock_status_bar = Mock()
            mock_footer = Mock()

            def mock_query_one(selector, widget_type=None):
                if selector == "#status-bar":
                    return mock_status_bar
                elif selector == "#custom-footer":
                    return mock_footer
                return Mock()

            app.query_one = mock_query_one

            # Add test hosts_file for footer status generation
            app.hosts_file = HostsFile()
            app.hosts_file.add_entry(
                HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
            )
            app.hosts_file.add_entry(
                HostEntry(
                    ip_address="192.168.1.1", hostnames=["router"], is_active=False
                )
            )

            app.update_status("Custom status message")

            # Verify status bar was updated with custom message
            mock_status_bar.update.assert_called_with("Custom status message")
            mock_status_bar.remove_class.assert_called_with("hidden")
            # Verify footer status was updated with current status (not the custom message)
            mock_footer.set_status.assert_called_once()
            footer_status = mock_footer.set_status.call_args[0][0]
            assert "2 entries" in footer_status
            assert "Read-only" in footer_status
            # Verify timer was set for auto-clearing
            app.set_timer.assert_called_once()

    def test_action_reload(self):
        """Test reload action."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.load_hosts_file = Mock()
            app.update_status = Mock()

            app.action_reload()

            app.load_hosts_file.assert_called_once()
            app.update_status.assert_called_with("Hosts file reloaded")

    def test_action_help(self):
        """Test help action."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.action_show_help_panel = Mock()

            app.action_help()

            # Should call the built-in help action
            app.action_show_help_panel.assert_called_once()

    def test_action_config(self):
        """Test config action opens modal."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.push_screen = Mock()

            app.action_config()

            # Should push config modal screen
            app.push_screen.assert_called_once()
            args = app.push_screen.call_args[0]
            assert len(args) >= 1  # ConfigModal instance

    def test_action_sort_by_ip_ascending(self):
        """Test sorting by IP address in ascending order."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Add test entries in reverse order
            app.hosts_file = HostsFile()
            app.hosts_file.add_entry(
                HostEntry(ip_address="192.168.1.1", hostnames=["router"])
            )
            app.hosts_file.add_entry(
                HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
            )
            app.hosts_file.add_entry(
                HostEntry(ip_address="10.0.0.1", hostnames=["test"])
            )

            # Mock the table_handler methods to avoid UI queries
            app.table_handler.populate_entries_table = Mock()
            app.table_handler.restore_cursor_position = Mock()
            app.update_status = Mock()

            app.action_sort_by_ip()

            # Check that entries are sorted by IP address
            assert app.hosts_file.entries[0].ip_address == "10.0.0.1"  # Sorted by IP
            assert app.hosts_file.entries[1].ip_address == "127.0.0.1"
            assert app.hosts_file.entries[2].ip_address == "192.168.1.1"

            assert app.sort_column == "ip"
            assert app.sort_ascending is True
            app.table_handler.populate_entries_table.assert_called_once()

    def test_action_sort_by_hostname_ascending(self):
        """Test sorting by hostname in ascending order."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Add test entries in reverse alphabetical order
            app.hosts_file = HostsFile()
            app.hosts_file.add_entry(
                HostEntry(ip_address="127.0.0.1", hostnames=["zebra"])
            )
            app.hosts_file.add_entry(
                HostEntry(ip_address="192.168.1.1", hostnames=["alpha"])
            )
            app.hosts_file.add_entry(
                HostEntry(ip_address="10.0.0.1", hostnames=["beta"])
            )

            # Mock the table_handler methods to avoid UI queries
            app.table_handler.populate_entries_table = Mock()
            app.table_handler.restore_cursor_position = Mock()
            app.update_status = Mock()

            app.action_sort_by_hostname()

            # Check that entries are sorted alphabetically
            assert app.hosts_file.entries[0].hostnames[0] == "alpha"
            assert app.hosts_file.entries[1].hostnames[0] == "beta"
            assert app.hosts_file.entries[2].hostnames[0] == "zebra"

            assert app.sort_column == "hostname"
            assert app.sort_ascending is True
            app.table_handler.populate_entries_table.assert_called_once()

    def test_data_table_row_highlighted_event(self):
        """Test DataTable row highlighting event handling."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Mock the details_handler and table_handler methods
            app.details_handler.update_entry_details = Mock()
            app.table_handler.display_index_to_actual_index = Mock(return_value=2)

            # Create mock event with required parameters
            mock_table = Mock()
            mock_table.id = "entries-table"
            event = Mock()
            event.data_table = mock_table
            event.cursor_row = 2

            app.on_data_table_row_highlighted(event)

            # Should update selected index and details
            assert app.selected_entry_index == 2
            app.details_handler.update_entry_details.assert_called_once()
            app.table_handler.display_index_to_actual_index.assert_called_once_with(2)

    def test_data_table_header_selected_ip_column(self):
        """Test DataTable header selection for IP column."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.action_sort_by_ip = Mock()

            # Create mock event for IP column
            mock_table = Mock()
            mock_table.id = "entries-table"
            event = Mock()
            event.data_table = mock_table
            event.column_key = "IP Address"

            app.on_data_table_header_selected(event)

            app.action_sort_by_ip.assert_called_once()

    def test_restore_cursor_position_logic(self):
        """Test cursor position restoration logic."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Mock the query_one method to avoid UI dependencies
            mock_table = Mock()
            app.query_one = Mock(return_value=mock_table)
            app.update_entry_details = Mock()

            # Add test entries
            app.hosts_file = HostsFile()
            entry1 = HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
            entry2 = HostEntry(ip_address="192.168.1.1", hostnames=["router"])
            app.hosts_file.add_entry(entry1)
            app.hosts_file.add_entry(entry2)

            # Test the logic without UI dependencies
            # Find the index of entry2
            target_index = None
            for i, entry in enumerate(app.hosts_file.entries):
                if (
                    entry.ip_address == entry2.ip_address
                    and entry.hostnames == entry2.hostnames
                ):
                    target_index = i
                    break

            # Should find the matching entry at index 1
            assert target_index == 1

    def test_app_bindings_defined(self):
        """Test that application has expected key bindings."""
        with patch("hosts.tui.app.HostsParser"), patch("hosts.tui.app.Config"):
            app = HostsManagerApp()

            # Check that bindings are defined
            assert len(app.BINDINGS) >= 6

            # Check specific bindings exist (handle both Binding objects and tuples)
            binding_keys = []
            for binding in app.BINDINGS:
                if hasattr(binding, "key"):
                    # Binding object
                    binding_keys.append(binding.key)
                elif isinstance(binding, tuple) and len(binding) >= 1:
                    # Tuple format (key, action, description)
                    binding_keys.append(binding[0])

            assert "q" in binding_keys
            assert "r" in binding_keys
            assert "question_mark" in binding_keys  # Help binding (? key)
            assert "i" in binding_keys
            assert "n" in binding_keys
            assert "c" in binding_keys
            assert "ctrl+c" in binding_keys

    def test_radio_set_event_handling_ip_entry(self):
        """Test radio set event handling for IP entry type."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.edit_handler.handle_entry_type_change = Mock()

            # Create mock radio set event for IP entry
            mock_radio_set = Mock()
            mock_radio_set.id = "edit-entry-type-radio"
            mock_pressed_radio = Mock()
            mock_pressed_radio.id = "edit-ip-entry-radio"
            
            event = Mock()
            event.radio_set = mock_radio_set
            event.pressed = mock_pressed_radio

            app.on_radio_set_changed(event)

            # Should handle IP entry type change
            app.edit_handler.handle_entry_type_change.assert_called_once_with("ip")

    def test_radio_set_event_handling_dns_entry(self):
        """Test radio set event handling for DNS entry type."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.edit_handler.handle_entry_type_change = Mock()

            # Create mock radio set event for DNS entry
            mock_radio_set = Mock()
            mock_radio_set.id = "edit-entry-type-radio"
            mock_pressed_radio = Mock()
            mock_pressed_radio.id = "edit-dns-entry-radio"
            
            event = Mock()
            event.radio_set = mock_radio_set
            event.pressed = mock_pressed_radio

            app.on_radio_set_changed(event)

            # Should handle DNS entry type change
            app.edit_handler.handle_entry_type_change.assert_called_once_with("dns")

    def test_entry_type_detection_ip_entry(self):
        """Test entry type detection for IP entries."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Add IP entry (no DNS name)
            app.hosts_file = HostsFile()
            ip_entry = HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
            app.hosts_file.add_entry(ip_entry)
            app.selected_entry_index = 0

            entry_type = app.edit_handler.get_current_entry_type()

            assert entry_type == "ip"

    def test_entry_type_detection_dns_entry(self):
        """Test entry type detection for DNS entries."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Add DNS entry with DNS name
            app.hosts_file = HostsFile()
            dns_entry = HostEntry(ip_address="0.0.0.0", hostnames=["example"])
            dns_entry.dns_name = "example.com"
            app.hosts_file.add_entry(dns_entry)
            app.selected_entry_index = 0

            entry_type = app.edit_handler.get_current_entry_type()

            assert entry_type == "dns"

    def test_field_visibility_ip_type(self):
        """Test field visibility logic for IP entry type."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Mock the section elements
            mock_ip_section = Mock()
            mock_dns_section = Mock()

            def mock_query_one(selector):
                if selector == "#edit-ip-section":
                    return mock_ip_section
                elif selector == "#edit-dns-section":
                    return mock_dns_section
                return Mock()

            app.query_one = mock_query_one

            app.edit_handler.update_field_visibility(show_ip=True, show_dns=False)

            # IP section should be visible, DNS section hidden
            mock_ip_section.remove_class.assert_called_with("hidden")
            mock_dns_section.add_class.assert_called_with("hidden")

    def test_field_visibility_dns_type(self):
        """Test field visibility logic for DNS entry type."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Mock the section elements
            mock_ip_section = Mock()
            mock_dns_section = Mock()

            def mock_query_one(selector):
                if selector == "#edit-ip-section":
                    return mock_ip_section
                elif selector == "#edit-dns-section":
                    return mock_dns_section
                return Mock()

            app.query_one = mock_query_one

            app.edit_handler.update_field_visibility(show_ip=False, show_dns=True)

            # DNS section should be visible, IP section hidden
            mock_ip_section.add_class.assert_called_with("hidden")
            mock_dns_section.remove_class.assert_called_with("hidden")

    def test_populate_edit_form_with_ip_type_detection(self):
        """Test edit form population with IP type detection."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.entry_edit_mode = True
            app.set_timer = Mock()  # Mock set_timer to avoid event loop issues

            # Add IP entry
            app.hosts_file = HostsFile()
            ip_entry = HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
            app.hosts_file.add_entry(ip_entry)
            app.selected_entry_index = 0

            # Mock radio set and buttons
            mock_radio_set = Mock()
            mock_ip_radio = Mock()
            mock_dns_radio = Mock()

            def mock_query_one(selector):
                if selector == "#edit-entry-type-radio":
                    return mock_radio_set
                elif selector == "#edit-ip-entry-radio":
                    return mock_ip_radio
                elif selector == "#edit-dns-entry-radio":
                    return mock_dns_radio
                return Mock()

            app.query_one = mock_query_one
            app.edit_handler.handle_entry_type_change = Mock()

            # Test that the method can be called without errors
            try:
                app.edit_handler.populate_edit_form_with_type_detection()
                # Method executed successfully
                assert True
            except Exception as e:
                # Method should not raise exceptions
                assert False, f"Method raised unexpected exception: {e}"

    def test_populate_edit_form_with_dns_type_detection(self):
        """Test edit form population with DNS type detection."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.entry_edit_mode = True

            # Add DNS entry
            app.hosts_file = HostsFile()
            dns_entry = HostEntry(ip_address="0.0.0.0", hostnames=["example"])
            dns_entry.dns_name = "example.com"
            app.hosts_file.add_entry(dns_entry)
            app.selected_entry_index = 0

            # Mock radio set, buttons, and DNS input with proper value tracking
            mock_radio_set = Mock()
            mock_ip_radio = Mock()
            mock_dns_radio = Mock()
            
            # Use a simple object to track value assignment
            class MockDNSInput:
                def __init__(self):
                    self.value = ""
            
            mock_dns_input = MockDNSInput()

            def mock_query_one(selector, widget_type=None):
                if selector == "#edit-entry-type-radio":
                    return mock_radio_set
                elif selector == "#edit-ip-entry-radio":
                    return mock_ip_radio
                elif selector == "#edit-dns-entry-radio":
                    return mock_dns_radio
                elif selector == "#dns-name-input":
                    return mock_dns_input
                return Mock()

            app.query_one = mock_query_one
            app.edit_handler.handle_entry_type_change = Mock()

            app.edit_handler.populate_edit_form_with_type_detection()

            # Should set DNS radio button as pressed and populate DNS field
            assert mock_radio_set.pressed_button == mock_dns_radio
            assert mock_dns_input.value == "example.com"
            app.edit_handler.handle_entry_type_change.assert_called_with("dns")

    def test_edit_form_initialization_calls_type_detection(self):
        """Test that edit form initialization calls type detection."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()

            # Mock form elements
            mock_details_display = Mock()
            mock_edit_form = Mock()
            mock_ip_input = Mock()
            mock_hostname_input = Mock()
            mock_comment_input = Mock()
            mock_active_checkbox = Mock()

            def mock_query_one(selector, widget_type=None):
                if selector == "#entry-details-display":
                    return mock_details_display
                elif selector == "#entry-edit-form":
                    return mock_edit_form
                elif selector == "#ip-input":
                    return mock_ip_input
                elif selector == "#hostname-input":
                    return mock_hostname_input
                elif selector == "#comment-input":
                    return mock_comment_input
                elif selector == "#active-checkbox":
                    return mock_active_checkbox
                return Mock()

            app.query_one = mock_query_one

            # Add test entry
            app.hosts_file = HostsFile()
            test_entry = HostEntry(ip_address="127.0.0.1", hostnames=["localhost"])
            app.hosts_file.add_entry(test_entry)
            app.selected_entry_index = 0

            # Mock the type detection method
            app.edit_handler.populate_edit_form_with_type_detection = Mock()

            app.details_handler.update_edit_form()

            # Should call type detection method
            app.edit_handler.populate_edit_form_with_type_detection.assert_called_once()

    def test_dns_resolution_restricted_to_edit_mode(self):
        """Test that DNS resolution is only allowed in edit mode."""
        mock_parser = Mock(spec=HostsParser)
        mock_config = Mock(spec=Config)

        with (
            patch("hosts.tui.app.HostsParser", return_value=mock_parser),
            patch("hosts.tui.app.Config", return_value=mock_config),
        ):
            app = HostsManagerApp()
            app.update_status = Mock()

            # Add test DNS entry
            app.hosts_file = HostsFile()
            dns_entry = HostEntry(ip_address="0.0.0.0", hostnames=["example"])
            dns_entry.dns_name = "example.com"
            app.hosts_file.add_entry(dns_entry)
            app.selected_entry_index = 0

            # Test 1: DNS resolution blocked in read-only mode (default)
            assert app.edit_mode is False

            # Test action_refresh_dns in read-only mode
            app.action_refresh_dns()
            app.update_status.assert_called_with(
                "❌ Cannot resolve DNS names: Application is in read-only mode. Press 'Ctrl+E' to enable edit mode."
            )

            # Reset mock
            app.update_status.reset_mock()

            # Test action_update_single_dns in read-only mode
            app.action_update_single_dns()
            app.update_status.assert_called_with(
                "❌ Cannot resolve DNS names: Application is in read-only mode. Press 'Ctrl+E' to enable edit mode."
            )

            # Test 2: DNS resolution allowed in edit mode
            app.edit_mode = True
            app.update_status.reset_mock()

            # Mock DNS service and other dependencies
            app.dns_service.resolve_entry_async = Mock()
            app.manager.save_hosts_file = Mock(return_value=(True, "Success"))
            app.table_handler.populate_entries_table = Mock()
            app.details_handler.update_entry_details = Mock()
            app.run_worker = Mock()

            # Test action_refresh_dns in edit mode - should proceed
            app.action_refresh_dns()
            # Should not show error message about read-only mode
            error_calls = [call for call in app.update_status.call_args_list 
                          if "read-only mode" in str(call)]
            assert len(error_calls) == 0
            # Should start DNS resolution
            app.run_worker.assert_called()

            # Reset mocks
            app.update_status.reset_mock()
            app.run_worker.reset_mock()

            # Test action_update_single_dns in edit mode - should proceed
            app.action_update_single_dns()
            # Should not show error message about read-only mode
            error_calls = [call for call in app.update_status.call_args_list 
                          if "read-only mode" in str(call)]
            assert len(error_calls) == 0
            # Should start DNS resolution
            app.run_worker.assert_called()

    def test_main_function(self):
        """Test main entry point function."""
        with patch("hosts.main.HostsManagerApp") as mock_app_class:
            mock_app = Mock()
            mock_app_class.return_value = mock_app

            from hosts.main import main

            main()

            # Should create and run app
            mock_app_class.assert_called_once()
            mock_app.run.assert_called_once()
