#!/usr/bin/env python3
"""
souleyez.plugins.routersploit_exploit

RouterSploit exploit execution plugin.
Runs specific exploits against vulnerable routers.
"""

import shutil
import subprocess
import time
from typing import List

from souleyez.security.validation import ValidationError, validate_target

from .plugin_base import PluginBase

HELP = {
    "name": "RouterSploit Exploit — Router Exploitation",
    "description": (
        "Execute RouterSploit exploits against vulnerable routers.\n\n"
        "After scanning with 'routersploit', use this plugin to run specific "
        "exploits against identified vulnerabilities.\n\n"
        "Common exploit categories:\n"
        "- creds/ - Credential extraction and default logins\n"
        "- exploits/ - Remote code execution, auth bypass\n"
        "- scanners/ - Additional vulnerability detection\n\n"
        "Quick tips:\n"
        "- Run 'routersploit' scanner first to identify vulns\n"
        "- Check exploit options with 'show options' in RSF\n"
        "- Most exploits need target IP and port\n"
        "- Some exploits give you a shell, others extract creds\n"
    ),
    "usage": 'souleyez jobs enqueue routersploit_exploit <target> --args "<module>"',
    "examples": [
        'souleyez jobs enqueue routersploit_exploit 192.168.1.1 --args "exploits/routers/netgear/dgn1000_dgn2200_rce"',
        'souleyez jobs enqueue routersploit_exploit 192.168.1.1 --args "creds/routers/dlink/dcs_default_creds"',
        'souleyez jobs enqueue routersploit_exploit 192.168.1.1 --args "exploits/routers/dlink/dir_815_850l_rce"',
    ],
    "flags": [
        ["--port PORT", "Target port (default: 80)"],
        ["--ssl", "Use HTTPS"],
    ],
    "presets": [
        {
            "name": "Netgear RCE",
            "args": ["exploits/routers/netgear/dgn1000_dgn2200_rce"],
            "desc": "Netgear DGN1000/2200 RCE",
        },
        {
            "name": "D-Link RCE",
            "args": ["exploits/routers/dlink/dir_815_850l_rce"],
            "desc": "D-Link DIR-815/850L RCE",
        },
        {
            "name": "Default Creds",
            "args": ["creds/generic/http_default_creds"],
            "desc": "Test default HTTP credentials",
        },
    ],
    "help_sections": [
        {
            "title": "Popular Exploits",
            "color": "cyan",
            "content": [
                {
                    "title": "Netgear",
                    "desc": "Common Netgear exploits",
                    "tips": [
                        "dgn1000_dgn2200_rce - RCE via web interface",
                        "wnr2000_rce - WNR2000 router RCE",
                        "r7000_r6400_rce - R7000/R6400 command injection",
                    ],
                },
                {
                    "title": "D-Link",
                    "desc": "Common D-Link exploits",
                    "tips": [
                        "dir_815_850l_rce - DIR-815/850L RCE",
                        "dcs_default_creds - IP camera default creds",
                        "dir_300_600_rce - DIR-300/600 RCE",
                    ],
                },
                {
                    "title": "TP-Link",
                    "desc": "Common TP-Link exploits",
                    "tips": [
                        "archer_c2_c20i_rce - Archer C2/C20i RCE",
                        "wr740nd_rce - WR740ND command injection",
                    ],
                },
            ],
        }
    ],
}


class RouterSploitExploitPlugin(PluginBase):
    name = "RouterSploit Exploit"
    tool = "rsf"
    category = "exploitation"
    HELP = HELP

    def check_tool_available(self) -> tuple:
        """Check if RouterSploit is available."""
        rsf_path = shutil.which("rsf")
        if rsf_path:
            return True, None

        try:
            import routersploit

            return True, None
        except ImportError:
            pass

        return False, (
            "RouterSploit not found. Install with:\n"
            "  pipx install routersploit\n"
            "  # or\n"
            "  git clone https://github.com/threat9/routersploit"
        )

    def build_command(
        self, target: str, args: List[str] = None, label: str = "", log_path: str = None
    ):
        """Build RouterSploit exploit command."""
        args = args or []

        if not args:
            if log_path:
                with open(log_path, "w") as f:
                    f.write("ERROR: Module path required\n")
                    f.write("Example: exploits/routers/netgear/dgn1000_dgn2200_rce\n")
            return None

        # Validate target
        try:
            target = validate_target(target)
        except ValidationError as e:
            if log_path:
                with open(log_path, "w") as f:
                    f.write(f"ERROR: Invalid target: {e}\n")
            return None

        # Parse module and options
        module = args[0]
        port = "80"
        ssl = False

        i = 1
        while i < len(args):
            if args[i] == "--port" and i + 1 < len(args):
                port = args[i + 1]
                i += 2
            elif args[i] == "--ssl":
                ssl = True
                port = "443" if port == "80" else port
                i += 1
            else:
                i += 1

        # Build RSF commands
        rsf_commands = f"""use {module}
set target {target}
set port {port}
run
exit
"""

        import os
        import tempfile

        fd, rc_file = tempfile.mkstemp(suffix=".rsf", prefix="rsf_exploit_")
        try:
            with os.fdopen(fd, "w") as f:
                f.write(rsf_commands)
        except Exception as e:
            if log_path:
                with open(log_path, "w") as f:
                    f.write(f"ERROR: Failed to create RSF script: {e}\n")
            return None

        rsf_bin = shutil.which("rsf")
        if rsf_bin:
            cmd = [rsf_bin, "-m", rc_file]
        else:
            cmd = ["python3", "-m", "routersploit", "-m", rc_file]

        return {"cmd": cmd, "timeout": 600, "_rc_file": rc_file}  # 10 minute timeout

    def run(
        self, target: str, args: List[str] = None, label: str = "", log_path: str = None
    ) -> int:
        """Execute RouterSploit exploit."""
        import os

        cmd_spec = self.build_command(target, args, label, log_path)
        if cmd_spec is None:
            return 1

        cmd = cmd_spec["cmd"]
        rc_file = cmd_spec.get("_rc_file")
        module = args[0] if args else "unknown"

        if log_path:
            with open(log_path, "w") as f:
                f.write(f"# RouterSploit Exploit on {target}\n")
                f.write(f"# Module: {module}\n")
                f.write(f"# Command: {' '.join(cmd)}\n")
                f.write(f"# Started: {time.strftime('%Y-%m-%d %H:%M:%S')}\n\n")

        try:
            with open(log_path, "a") as f:
                result = subprocess.run(
                    cmd, stdout=f, stderr=subprocess.STDOUT, timeout=cmd_spec["timeout"]
                )
            return result.returncode

        except subprocess.TimeoutExpired:
            if log_path:
                with open(log_path, "a") as f:
                    f.write("\n\n# ERROR: Exploit timed out\n")
            return 124
        except FileNotFoundError:
            if log_path:
                with open(log_path, "a") as f:
                    f.write("\n\n# ERROR: RouterSploit not found\n")
            return 127
        except Exception as e:
            if log_path:
                with open(log_path, "a") as f:
                    f.write(f"\n\n# ERROR: {e}\n")
            return 1
        finally:
            if rc_file and os.path.exists(rc_file):
                try:
                    os.unlink(rc_file)
                except:
                    pass


plugin = RouterSploitExploitPlugin()
