"""Step 16: Lock down OpenClaw services to localhost and show access instructions.

Detects whether the install is on a remote server (via $SSH_CONNECTION) or
a local machine, then shows context-appropriate instructions for accessing
the OpenClaw web interface.
"""

from ..base_step import BaseStep


class SecurityHardeningStep(BaseStep):
    name = "Security Hardening"
    description = "Bind services to localhost and show access instructions"
    timeout = 60
    allow_retry = True
    max_retries = 1

    def validate_preconditions(self) -> tuple[bool, str]:
        import os
        import shutil

        if not os.path.isfile("/etc/openclaw/config.json"):
            return False, "/etc/openclaw/config.json not found"
        if not shutil.which("systemctl"):
            return False, "systemctl not found"
        return True, ""

    def command(self) -> str:
        return (
            "set -e\n"
            "\n"
            "# ── 1. Normalize config baseline ──\n"
            "echo 'Normalizing configuration...'\n"
            "openclaw config write 2>&1\n"
            "echo ''\n"
            "\n"
            "# ── 2. Patch config: bind server + gateway to localhost ──\n"
            "echo 'Binding services to localhost...'\n"
            "python3 << 'PYEOF'\n"
            "import json\n"
            "\n"
            "cfg_path = '/etc/openclaw/config.json'\n"
            "with open(cfg_path) as f:\n"
            "    cfg = json.load(f)\n"
            "\n"
            "changed = False\n"
            "for section in ('server', 'gateway'):\n"
            "    if section in cfg and cfg[section].get('host') != '127.0.0.1':\n"
            "        old = cfg[section].get('host', '(unset)')\n"
            "        cfg[section]['host'] = '127.0.0.1'\n"
            "        print(f'  {section}.host: {old} -> 127.0.0.1')\n"
            "        changed = True\n"
            "\n"
            "if changed:\n"
            "    with open(cfg_path, 'w') as f:\n"
            "        json.dump(cfg, f, indent=2)\n"
            "        f.write('\\n')\n"
            "    print('Config updated.')\n"
            "else:\n"
            "    print('Already bound to localhost — no changes needed.')\n"
            "PYEOF\n"
            "echo ''\n"
            "\n"
            "# ── 3. Validate patched config ──\n"
            "echo 'Validating configuration...'\n"
            "openclaw config validate 2>&1\n"
            "echo ''\n"
            "\n"
            "# ── 4. Restart both services with new binding ──\n"
            "echo 'Restarting services...'\n"
            "systemctl restart openclaw.service\n"
            "systemctl restart openclaw-gateway.service\n"
            "sleep 3\n"
            "\n"
            "# ── 5. Verify services are active ──\n"
            "SRV=$(systemctl is-active openclaw.service 2>/dev/null || echo 'inactive')\n"
            "GW=$(systemctl is-active openclaw-gateway.service 2>/dev/null || echo 'inactive')\n"
            "echo \"  openclaw.service:         $SRV\"\n"
            "echo \"  openclaw-gateway.service: $GW\"\n"
            "\n"
            "if [ \"$SRV\" != 'active' ] || [ \"$GW\" != 'active' ]; then\n"
            "  echo '' >&2\n"
            "  echo 'ERROR: Services failed to restart after lockdown' >&2\n"
            "  journalctl -u openclaw.service -u openclaw-gateway.service "
            "--no-pager -n 20 2>&1 || true\n"
            "  exit 1\n"
            "fi\n"
            "echo ''\n"
            "\n"
            "# ── 6. Verify localhost binding (retry up to 10s) ──\n"
            "echo 'Verifying port binding...'\n"
            "BIND_OK=0\n"
            "for i in $(seq 1 10); do\n"
            "  WIDE=''\n"
            "  ss -tlnp 2>/dev/null | grep -q '0.0.0.0:3100' && WIDE=1\n"
            "  ss -tlnp 2>/dev/null | grep -q '0.0.0.0:3200' && WIDE=1\n"
            "  if [ -z \"$WIDE\" ]; then\n"
            "    BIND_OK=1\n"
            "    echo \"Ports bound to localhost after ${i}s\"\n"
            "    break\n"
            "  fi\n"
            "  sleep 1\n"
            "done\n"
            "if [ $BIND_OK -eq 0 ]; then\n"
            "  echo 'WARNING: Port 3100 still on 0.0.0.0' >&2\n"
            "  echo 'WARNING: Port 3200 still on 0.0.0.0' >&2\n"
            "fi\n"
            "ss -tlnp 2>/dev/null | grep -E ':3100|:3200' || true\n"
            "echo ''\n"
            "\n"
            "# ── 7. Access instructions (context-aware) ──\n"
            "echo '========================================================'\n"
            "echo '  OpenClaw Installation Complete!'\n"
            "echo '========================================================'\n"
            "echo ''\n"
            "echo '  Services are bound to 127.0.0.1 (localhost only).'\n"
            "echo '  Ports 3100/3200 are NOT exposed to the internet.'\n"
            "echo ''\n"
            "\n"
            "if [ -n \"$SSH_CONNECTION\" ]; then\n"
            "  # Remote server — user connected via SSH\n"
            "  SERVER_IP=$(echo \"$SSH_CONNECTION\" | awk '{print $3}')\n"
            "  if [ -z \"$SERVER_IP\" ]; then\n"
            "    SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}')\n"
            "  fi\n"
            "  echo '  Remote server detected. To access the web interface:'\n"
            "  echo ''\n"
            "  echo '  1. Open a NEW terminal on your local machine and run:'\n"
            "  echo ''\n"
            "  echo \"     ssh -L 3200:localhost:3200 root@${SERVER_IP}\"\n"
            "  echo ''\n"
            "  echo '  2. Keep that SSH session open, then open your browser:'\n"
            "  echo ''\n"
            "  echo '     http://localhost:3200'\n"
            "  echo ''\n"
            "  echo '  The SSH tunnel securely forwards your local port 3200'\n"
            "  echo '  to the server. This is the recommended access method.'\n"
            "else\n"
            "  # Local machine — no SSH session\n"
            "  echo '  Local install detected. Open your browser:'\n"
            "  echo ''\n"
            "  echo '     http://localhost:3200'\n"
            "fi\n"
            "\n"
            "echo ''\n"
            "echo '  Config:    /etc/openclaw/'\n"
            "echo '  Workspace: /var/lib/openclaw/'\n"
            "echo '  Logs:      journalctl -u openclaw'\n"
            "echo '========================================================'\n"
        )
