"""RabbitMQ Management HTTP API 客户端封装"""

import json
import sys
from urllib.parse import quote

import requests
from requests.auth import HTTPBasicAuth


class RabbitMQClient:
    """封装 RabbitMQ Management HTTP API 的请求逻辑"""

    def __init__(self, host: str, port: int, username: str, password: str, scheme: str = "http"):
        self.base_url = f"{scheme}://{host}:{port}/api"
        self.auth = HTTPBasicAuth(username, password)
        self.session = requests.Session()
        self.session.auth = self.auth
        self.session.headers.update({"Content-Type": "application/json"})

    def _url(self, path: str) -> str:
        """构建完整 API URL"""
        return f"{self.base_url}/{path.lstrip('/')}"

    def _handle_response(self, resp: requests.Response):
        """统一处理响应，失败时输出错误信息并退出"""
        if resp.status_code == 404:
            print("Error: Resource not found (404)", file=sys.stderr)
            sys.exit(1)
        if resp.status_code == 401:
            print("Error: Authentication failed (401)", file=sys.stderr)
            sys.exit(1)
        if not resp.ok:
            try:
                body = resp.json()
                reason = body.get("reason", resp.text)
            except Exception:
                reason = resp.text
            print(f"Error: {resp.status_code} - {reason}", file=sys.stderr)
            sys.exit(1)
        # 204 No Content
        if resp.status_code == 204:
            return None
        return resp.json()

    def get(self, path: str, params: dict = None):
        resp = self.session.get(self._url(path), params=params)
        return self._handle_response(resp)

    def put(self, path: str, body: dict = None):
        resp = self.session.put(self._url(path), data=json.dumps(body or {}))
        return self._handle_response(resp)

    def post(self, path: str, body: dict = None):
        resp = self.session.post(self._url(path), data=json.dumps(body or {}))
        return self._handle_response(resp)

    def delete(self, path: str):
        resp = self.session.delete(self._url(path))
        return self._handle_response(resp)

    @staticmethod
    def encode_name(name: str) -> str:
        """对路径中的资源名称进行 URL 编码（支持 / 等特殊字符）"""
        return quote(name, safe="")
