"""Tests for msf_exploit plugin command building.

These tests verify that the Metasploit exploit plugin correctly builds
commands for different exploit types, particularly handling exploits
that don't need LHOST/PAYLOAD (like bind shell backdoors).
"""

import pytest


class TestMsfExploitPayloadHandling:
    """Test payload and LHOST handling for different exploit types."""

    def test_vsftpd_backdoor_no_payload(self):
        """vsftpd_234_backdoor should not set LHOST or PAYLOAD.

        This exploit opens a bind shell on port 6200 - it doesn't need
        a reverse payload or LHOST configuration.

        Regression test for job #746 failure.
        """
        from souleyez.plugins.msf_exploit import MsfExploitPlugin

        plugin = MsfExploitPlugin()
        result = plugin._build_console_command(
            target="192.168.1.240",
            exploit_path="exploit/unix/ftp/vsftpd_234_backdoor",
            extra_opts=[],
        )

        command_str = result.get("cmd", [])
        # The command is a list, join to check content
        if isinstance(command_str, list):
            command_str = " ".join(command_str)

        # vsftpd backdoor should NOT have LHOST or PAYLOAD
        assert (
            "LHOST" not in command_str
        ), f"vsftpd backdoor should not set LHOST. Command: {command_str}"
        assert (
            "PAYLOAD" not in command_str
        ), f"vsftpd backdoor should not set PAYLOAD. Command: {command_str}"

    def test_usermap_script_no_payload(self):
        """usermap_script (Samba) should not set LHOST or PAYLOAD.

        This exploit uses command execution, not a reverse shell.
        """
        from souleyez.plugins.msf_exploit import MsfExploitPlugin

        plugin = MsfExploitPlugin()
        result = plugin._build_console_command(
            target="192.168.1.240",
            exploit_path="exploit/multi/samba/usermap_script",
            extra_opts=[],
        )

        command_str = result.get("cmd", [])
        if isinstance(command_str, list):
            command_str = " ".join(command_str)

        assert "LHOST" not in command_str
        assert "PAYLOAD" not in command_str

    def test_distcc_exec_no_payload(self):
        """distcc_exec should not set LHOST or PAYLOAD.

        This exploit uses direct command execution.
        """
        from souleyez.plugins.msf_exploit import MsfExploitPlugin

        plugin = MsfExploitPlugin()
        result = plugin._build_console_command(
            target="192.168.1.240",
            exploit_path="exploit/unix/misc/distcc_exec",
            extra_opts=[],
        )

        command_str = result.get("cmd", [])
        if isinstance(command_str, list):
            command_str = " ".join(command_str)

        assert "LHOST" not in command_str
        assert "PAYLOAD" not in command_str

    def test_regular_exploit_has_payload(self):
        """Regular exploits SHOULD have LHOST and PAYLOAD set."""
        from souleyez.plugins.msf_exploit import MsfExploitPlugin

        plugin = MsfExploitPlugin()
        result = plugin._build_console_command(
            target="192.168.1.240",
            exploit_path="exploit/windows/smb/ms17_010_eternalblue",
            extra_opts=[],
        )

        command_str = result.get("cmd", [])
        if isinstance(command_str, list):
            command_str = " ".join(command_str)

        # Regular exploits SHOULD have LHOST and PAYLOAD
        assert (
            "LHOST" in command_str or "PAYLOAD" in command_str
        ), "Regular exploits should set LHOST/PAYLOAD"

    def test_explicit_payload_preserved(self):
        """User-specified PAYLOAD should be preserved."""
        from souleyez.plugins.msf_exploit import MsfExploitPlugin

        plugin = MsfExploitPlugin()
        result = plugin._build_console_command(
            target="192.168.1.240",
            exploit_path="exploit/windows/smb/ms17_010_eternalblue",
            extra_opts=["PAYLOAD=windows/x64/meterpreter/reverse_tcp"],
        )

        command_str = result.get("cmd", [])
        if isinstance(command_str, list):
            command_str = " ".join(command_str)

        # User-specified payload should be in command
        assert "windows/x64/meterpreter/reverse_tcp" in command_str
