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

Strategy:
  1. Try `openclaw gateway install` + `openclaw node install` (preferred).
     These create user-level services in ~/.config/systemd/user/.
     We copy them to /etc/systemd/system/ for system-level boot persistence.
  2. Fallback: write service files manually using the known ExecStart paths
     discovered from the OpenClaw CLI source:
       - Gateway: /usr/bin/node <pkg>/dist/index.js gateway --port 18789
       - Node host: /usr/bin/node <pkg>/dist/index.js node run
"""

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"
            "pkill -f 'openclaw.*gateway' 2>/dev/null || true\n"
            "pkill -f 'openclaw.*node.*run' 2>/dev/null || true\n"
            "systemctl stop openclaw-gateway.service 2>/dev/null || true\n"
            "systemctl stop openclaw.service 2>/dev/null || true\n"
            "systemctl stop openclaw-node.service 2>/dev/null || true\n"
            "sleep 2\n"
            "echo ''\n"
            "\n"
            "# Find the openclaw package directory (npm global)\n"
            "OPENCLAW_PKG=$(node -e \"console.log(require.resolve('openclaw/package.json').replace('/package.json',''))\" 2>/dev/null)\n"
            "if [ -z \"$OPENCLAW_PKG\" ]; then\n"
            "  echo 'ERROR: Cannot find openclaw package directory' >&2\n"
            "  exit 1\n"
            "fi\n"
            "echo \"OpenClaw package: $OPENCLAW_PKG\"\n"
            "\n"
            "NODE_BIN=$(which node)\n"
            "echo \"Node binary: $NODE_BIN\"\n"
            "\n"
            "# Verify the entry point exists\n"
            "ENTRY=\"$OPENCLAW_PKG/dist/index.js\"\n"
            "if [ ! -f \"$ENTRY\" ]; then\n"
            "  echo \"ERROR: Entry point $ENTRY not found\" >&2\n"
            "  exit 1\n"
            "fi\n"
            "echo \"Entry point: $ENTRY\"\n"
            "echo ''\n"
            "\n"
            "# Determine gateway port from config, default 18789\n"
            "GW_PORT=$(openclaw config get gateway.port 2>/dev/null || echo '18789')\n"
            "# Strip any non-numeric chars (error messages, etc)\n"
            "GW_PORT=$(echo \"$GW_PORT\" | grep -oE '[0-9]+' | head -1)\n"
            "GW_PORT=${GW_PORT:-18789}\n"
            "echo \"Gateway port: $GW_PORT\"\n"
            "echo ''\n"
            "\n"
            "# Create workspace directory\n"
            "mkdir -p /var/lib/openclaw\n"
            "\n"
            "# ============================================================\n"
            "# Strategy 1: Use openclaw CLI to generate service files\n"
            "# ============================================================\n"
            "echo 'Attempting: openclaw gateway install ...'\n"
            "set +e\n"
            "GW_OUTPUT=$(openclaw gateway install --force 2>&1)\n"
            "GW_RC=$?\n"
            "echo \"$GW_OUTPUT\"\n"
            "\n"
            "echo ''\n"
            "echo 'Attempting: openclaw node install ...'\n"
            "NODE_OUTPUT=$(openclaw node install 2>&1)\n"
            "NODE_RC=$?\n"
            "echo \"$NODE_OUTPUT\"\n"
            "set -e\n"
            "echo ''\n"
            "\n"
            "# CLI installs to user-level systemd (~/.config/systemd/user/).\n"
            "# Copy to system-level for boot persistence on headless servers.\n"
            "USER_SVCDIR=\"$HOME/.config/systemd/user\"\n"
            "SYS_SVCDIR=\"/etc/systemd/system\"\n"
            "\n"
            "HAVE_GW_SVC=false\n"
            "HAVE_NODE_SVC=false\n"
            "\n"
            "if [ -f \"$USER_SVCDIR/openclaw-gateway.service\" ]; then\n"
            "  cp \"$USER_SVCDIR/openclaw-gateway.service\" \"$SYS_SVCDIR/openclaw-gateway.service\"\n"
            "  # Fix WantedBy for system-level\n"
            "  sed -i 's/WantedBy=default.target/WantedBy=multi-user.target/' \"$SYS_SVCDIR/openclaw-gateway.service\"\n"
            "  echo 'Copied openclaw-gateway.service to system level'\n"
            "  HAVE_GW_SVC=true\n"
            "fi\n"
            "\n"
            "if [ -f \"$USER_SVCDIR/openclaw-node.service\" ]; then\n"
            "  cp \"$USER_SVCDIR/openclaw-node.service\" \"$SYS_SVCDIR/openclaw-node.service\"\n"
            "  sed -i 's/WantedBy=default.target/WantedBy=multi-user.target/' \"$SYS_SVCDIR/openclaw-node.service\"\n"
            "  echo 'Copied openclaw-node.service to system level'\n"
            "  HAVE_NODE_SVC=true\n"
            "fi\n"
            "\n"
            "# ============================================================\n"
            "# Strategy 2: Manual fallback if CLI didn't create files\n"
            "# ============================================================\n"
            "if [ \"$HAVE_GW_SVC\" = false ]; then\n"
            "  echo 'Creating openclaw-gateway.service (manual fallback)...'\n"
            "  cat > \"$SYS_SVCDIR/openclaw-gateway.service\" << SVCEOF\n"
            "[Unit]\n"
            "Description=OpenClaw Gateway\n"
            "After=network-online.target\n"
            "Wants=network-online.target\n"
            "\n"
            "[Service]\n"
            "Type=simple\n"
            "ExecStart=$NODE_BIN $ENTRY gateway --port $GW_PORT\n"
            "Restart=always\n"
            "RestartSec=5\n"
            "TimeoutStopSec=30\n"
            "SuccessExitStatus=0 143\n"
            "KillMode=control-group\n"
            "EnvironmentFile=-/etc/openclaw/env\n"
            "Environment=NODE_ENV=production\n"
            "WorkingDirectory=/var/lib/openclaw\n"
            "\n"
            "[Install]\n"
            "WantedBy=multi-user.target\n"
            "SVCEOF\n"
            "  echo '  -> $SYS_SVCDIR/openclaw-gateway.service'\n"
            "fi\n"
            "\n"
            "if [ \"$HAVE_NODE_SVC\" = false ]; then\n"
            "  echo 'Creating openclaw-node.service (manual fallback)...'\n"
            "  cat > \"$SYS_SVCDIR/openclaw-node.service\" << SVCEOF\n"
            "[Unit]\n"
            "Description=OpenClaw Node Host\n"
            "After=network-online.target\n"
            "Wants=network-online.target\n"
            "\n"
            "[Service]\n"
            "Type=simple\n"
            "ExecStart=$NODE_BIN $ENTRY node run --host 127.0.0.1 --port $GW_PORT\n"
            "Restart=always\n"
            "RestartSec=5\n"
            "TimeoutStopSec=30\n"
            "SuccessExitStatus=0 143\n"
            "KillMode=control-group\n"
            "EnvironmentFile=-/etc/openclaw/env\n"
            "Environment=NODE_ENV=production\n"
            "WorkingDirectory=/var/lib/openclaw\n"
            "\n"
            "[Install]\n"
            "WantedBy=multi-user.target\n"
            "SVCEOF\n"
            "  echo '  -> $SYS_SVCDIR/openclaw-node.service'\n"
            "fi\n"
            "echo ''\n"
            "\n"
            "# ============================================================\n"
            "# Reload, enable, and start\n"
            "# ============================================================\n"
            "echo 'Reloading systemd daemon...'\n"
            "systemctl daemon-reload\n"
            "echo ''\n"
            "\n"
            "echo 'Enabling services...'\n"
            "systemctl enable openclaw-gateway.service 2>&1 || true\n"
            "systemctl enable openclaw-node.service 2>&1 || true\n"
            "echo ''\n"
            "\n"
            "# Start services\n"
            "set +e\n"
            "echo 'Starting openclaw-gateway.service ...'\n"
            "systemctl start openclaw-gateway.service 2>&1\n"
            "GW_RC=$?\n"
            "echo 'Starting openclaw-node.service ...'\n"
            "systemctl start openclaw-node.service 2>&1\n"
            "NODE_RC=$?\n"
            "set -e\n"
            "echo ''\n"
            "\n"
            "# Wait for services to stabilize\n"
            "sleep 4\n"
            "\n"
            "# Show status\n"
            "echo '--- Service Status ---'\n"
            "systemctl --no-pager status openclaw-gateway.service 2>&1 || true\n"
            "echo ''\n"
            "systemctl --no-pager status openclaw-node.service 2>&1 || true\n"
            "echo ''\n"
            "\n"
            "# Verify services are actually running\n"
            "GW_ACTIVE=$(systemctl is-active openclaw-gateway.service 2>/dev/null || echo 'inactive')\n"
            "NODE_ACTIVE=$(systemctl is-active openclaw-node.service 2>/dev/null || echo 'inactive')\n"
            "\n"
            "echo \"openclaw-gateway.service: $GW_ACTIVE\"\n"
            "echo \"openclaw-node.service: $NODE_ACTIVE\"\n"
            "echo ''\n"
            "\n"
            "if [ \"$GW_ACTIVE\" != 'active' ] || [ \"$NODE_ACTIVE\" != 'active' ]; then\n"
            "  echo '--- Journal Logs ---'\n"
            "  journalctl -u openclaw-gateway.service -u openclaw-node.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.'"
        )
