"""Step 12: Create and enable systemd service units for OpenClaw.

Strategy:
  1. Run `openclaw service install` — creates both openclaw.service and
     openclaw-gateway.service, daemon-reloads, enables, and starts them.
  2. Fallback: write service files manually using the known entry points
     discovered from the @openclaw/cli source:
       - Server:  node <pkg>/lib/server.js    (port 3100)
       - Gateway: node <pkg>/lib/gateway.js --serve  (port 3200)
"""

from ..base_step import BaseStep


class SystemdStep(BaseStep):
    name = "Systemd Services"
    description = "Create and enable systemd units for OpenClaw"
    timeout = 120
    allow_retry = True
    max_retries = 2

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

        if not shutil.which("systemctl"):
            return False, "systemctl not found — systemd is required"
        if not shutil.which("openclaw"):
            return False, "openclaw binary not found — step 3 must complete first"
        return True, ""

    def command(self) -> str:
        return (
            "set -e\n"
            "\n"
            "# Stop any running openclaw processes to avoid port conflicts\n"
            "echo 'Stopping any running OpenClaw processes...'\n"
            "# Timeout prevents hanging when services are in a bad state\n"
            "timeout 10 systemctl stop openclaw-gateway.service 2>/dev/null || true\n"
            "timeout 10 systemctl stop openclaw.service 2>/dev/null || true\n"
            "# Kill any strays not managed by systemd\n"
            "pkill -f 'node.*server\\.js' 2>/dev/null || true\n"
            "pkill -f 'node.*gateway\\.js' 2>/dev/null || true\n"
            "sleep 1\n"
            "# SIGKILL anything still clinging to ports 3100/3200\n"
            "fuser -k 3100/tcp 2>/dev/null || true\n"
            "fuser -k 3200/tcp 2>/dev/null || true\n"
            "\n"
            "# Wait for ports to actually be free (up to 15s)\n"
            "echo 'Waiting for ports 3100/3200 to be released...'\n"
            "for i in $(seq 1 15); do\n"
            "  BUSY=''\n"
            "  ss -tlnp 2>/dev/null | grep -q ':3100 ' && BUSY=1\n"
            "  ss -tlnp 2>/dev/null | grep -q ':3200 ' && BUSY=1\n"
            "  if [ -z \"$BUSY\" ]; then\n"
            "    echo \"Ports free after ${i}s\"\n"
            "    break\n"
            "  fi\n"
            "  if [ $i -eq 15 ]; then\n"
            "    echo 'WARNING: Ports still busy after 15s — proceeding anyway'\n"
            "  fi\n"
            "  sleep 1\n"
            "done\n"
            "echo ''\n"
            "\n"
            "# Ensure workspace directory exists\n"
            "mkdir -p /var/lib/openclaw\n"
            "\n"
            "# ============================================================\n"
            "# Strategy 1: Use `openclaw service install`\n"
            "# Creates openclaw.service + openclaw-gateway.service,\n"
            "# daemon-reloads, enables, and starts both.\n"
            "# ============================================================\n"
            "echo 'Running: openclaw service install ...'\n"
            "set +e\n"
            "SVC_OUTPUT=$(openclaw service install 2>&1)\n"
            "SVC_RC=$?\n"
            "echo \"$SVC_OUTPUT\"\n"
            "set -e\n"
            "echo ''\n"
            "\n"
            "if [ $SVC_RC -eq 0 ]; then\n"
            "  echo 'openclaw service install succeeded.'\n"
            "else\n"
            "  echo 'openclaw service install failed (rc=$SVC_RC), trying manual fallback...'\n"
            "  echo ''\n"
            "\n"
            "  # ============================================================\n"
            "  # Strategy 2: Manual fallback\n"
            "  # ============================================================\n"
            "  NPM_ROOT=$(npm root -g 2>/dev/null)\n"
            "  PKG_DIR=\"$NPM_ROOT/@openclaw/cli\"\n"
            "  if [ ! -d \"$PKG_DIR\" ]; then\n"
            "    echo \"ERROR: @openclaw/cli not found at $PKG_DIR\" >&2\n"
            "    exit 1\n"
            "  fi\n"
            "  NODE_BIN=$(which node)\n"
            "  echo \"Node: $NODE_BIN\"\n"
            "  echo \"Package: $PKG_DIR\"\n"
            "  echo ''\n"
            "\n"
            "  cat > /etc/systemd/system/openclaw.service << SVCEOF\n"
            "[Unit]\n"
            "Description=OpenClaw Server\n"
            "After=network.target\n"
            "Wants=network-online.target\n"
            "\n"
            "[Service]\n"
            "Type=simple\n"
            "ExecStart=$NODE_BIN $PKG_DIR/lib/server.js\n"
            "Restart=on-failure\n"
            "RestartSec=5\n"
            "EnvironmentFile=-/etc/openclaw/env\n"
            "WorkingDirectory=/var/lib/openclaw\n"
            "StandardOutput=journal\n"
            "StandardError=journal\n"
            "SyslogIdentifier=openclaw\n"
            "\n"
            "[Install]\n"
            "WantedBy=multi-user.target\n"
            "SVCEOF\n"
            "  echo 'Written /etc/systemd/system/openclaw.service'\n"
            "\n"
            "  cat > /etc/systemd/system/openclaw-gateway.service << SVCEOF\n"
            "[Unit]\n"
            "Description=OpenClaw API Gateway\n"
            "After=openclaw.service\n"
            "Requires=openclaw.service\n"
            "\n"
            "[Service]\n"
            "Type=simple\n"
            "ExecStart=$NODE_BIN $PKG_DIR/lib/gateway.js --serve\n"
            "Restart=on-failure\n"
            "RestartSec=5\n"
            "EnvironmentFile=-/etc/openclaw/env\n"
            "WorkingDirectory=/var/lib/openclaw\n"
            "StandardOutput=journal\n"
            "StandardError=journal\n"
            "SyslogIdentifier=openclaw-gateway\n"
            "\n"
            "[Install]\n"
            "WantedBy=multi-user.target\n"
            "SVCEOF\n"
            "  echo 'Written /etc/systemd/system/openclaw-gateway.service'\n"
            "  echo ''\n"
            "\n"
            "  systemctl daemon-reload\n"
            "  systemctl enable openclaw.service openclaw-gateway.service\n"
            "  echo 'Starting openclaw.service ...'\n"
            "  systemctl start openclaw.service\n"
            "  echo 'Starting openclaw-gateway.service ...'\n"
            "  systemctl start openclaw-gateway.service\n"
            "fi\n"
            "\n"
            "# Wait for services to stabilize\n"
            "sleep 3\n"
            "\n"
            "# Verify services are actually running\n"
            "echo '--- Service Status ---'\n"
            "SRV_ACTIVE=$(systemctl is-active openclaw.service 2>/dev/null || echo 'inactive')\n"
            "GW_ACTIVE=$(systemctl is-active openclaw-gateway.service 2>/dev/null || echo 'inactive')\n"
            "\n"
            "echo \"openclaw.service: $SRV_ACTIVE\"\n"
            "echo \"openclaw-gateway.service: $GW_ACTIVE\"\n"
            "echo ''\n"
            "\n"
            "if [ \"$SRV_ACTIVE\" != 'active' ] || [ \"$GW_ACTIVE\" != 'active' ]; then\n"
            "  echo '--- Journal Logs ---'\n"
            "  journalctl -u openclaw.service -u openclaw-gateway.service "
            "--no-pager -n 30 2>&1 || true\n"
            "  echo ''\n"
            "  echo 'WARNING: One or both services are not running.' >&2\n"
            "  exit 1\n"
            "fi\n"
            "\n"
            "echo 'Systemd services configured and running.'"
        )
