"""CLI 入口点：使用 Google Fire 将命令类自动映射为子命令"""

import fire

from rmqadm.client import RabbitMQClient
from rmqadm.config import load_config, get_cluster, _print_clusters, DEFAULT_CONFIG_PATH
from rmqadm.commands.users import UsersCommands
from rmqadm.commands.vhosts import VhostsCommands
from rmqadm.commands.queues import QueuesCommands
from rmqadm.commands.exchanges import ExchangesCommands
from rmqadm.commands.bindings import BindingsCommands
from rmqadm.commands.connections import ConnectionsCommands
from rmqadm.commands.channels import ChannelsCommands
from rmqadm.commands.nodes import NodesCommands
from rmqadm.commands.permissions import PermissionsCommands
from rmqadm.commands.consumers import ConsumersCommands
from rmqadm.commands.policies import PoliciesCommands
from rmqadm.commands.operator_policies import OperatorPoliciesCommands
from rmqadm.commands.parameters import ParametersCommands, GlobalParametersCommands
from rmqadm.commands.limits import VhostLimitsCommands, UserLimitsCommands
from rmqadm.commands.definitions import DefinitionsCommands
from rmqadm.commands.health_check import HealthCheckCommands
from rmqadm.commands.feature_flags import FeatureFlagsCommands
from rmqadm.commands.rebalance import RebalanceCommands
from rmqadm.commands.streams import StreamsCommands
from rmqadm.formatter import print_table, print_json


class RmqAdm:
    """RabbitMQ 管理命令行工具

    通过集群别名连接（推荐）:
        rmqadm -c dev users list
        rmqadm --cluster rmq vhosts list
        rmqadm clusters                        # 列出所有已配置的集群

    手动指定连接参数:
        rmqadm --host localhost --port 15672 users list
        rmqadm --host rmq.example.com --username admin --password xxx queues list

    配置文件路径（默认）: ~/.config/rabbitmq/admin.json
    """

    def __init__(
        self,
        cluster: str = None,
        host: str = "localhost",
        port: int = 15672,
        username: str = "guest",
        password: str = "guest",
        vhost: str = "/",
        scheme: str = "http",
        profile: str = None,
    ):
        """
        Args:
            cluster: 集群别名，对应配置文件中的 name 字段（-c 简写）
            host:    RabbitMQ 主机地址（默认 localhost）
            port:    Management API 端口（默认 15672）
            username: 用户名（默认 guest）
            password: 密码（默认 guest）
            vhost:   默认 Virtual Host（默认 /）
            scheme:  协议 http 或 https（默认 http）
            profile: 配置文件路径（-p 简写，默认 ~/.config/rabbitmq/admin.json）
        """
        # 若指定了 cluster，从配置文件中加载连接参数，命令行参数可覆盖配置文件值
        if cluster is not None:
            clusters = load_config(profile)
            cfg = get_cluster(clusters, cluster)
            # 配置文件作为默认值；若用户还额外传了参数则以参数为准
            host = host if host != "localhost" else cfg.get("host", host)
            port = port if port != 15672 else cfg.get("port", port)
            username = username if username != "guest" else cfg.get("username", username)
            password = password if password != "guest" else cfg.get("password", password)
            vhost = vhost if vhost != "/" else cfg.get("vhost", vhost)
            scheme = scheme if scheme != "http" else cfg.get("scheme", scheme)

        rmq_client = RabbitMQClient(host, port, username, password, scheme)

        # ---- 核心资源命令 ----
        self.users = UsersCommands(rmq_client)
        self.vhosts = VhostsCommands(rmq_client)
        self.queues = QueuesCommands(rmq_client, default_vhost=vhost)
        self.exchanges = ExchangesCommands(rmq_client, default_vhost=vhost)
        self.bindings = BindingsCommands(rmq_client, default_vhost=vhost)
        self.streams = StreamsCommands(rmq_client, default_vhost=vhost)

        # ---- 连接 / 通道 / 消费者 ----
        self.connections = ConnectionsCommands(rmq_client)
        self.channels = ChannelsCommands(rmq_client)
        self.consumers = ConsumersCommands(rmq_client, default_vhost=vhost)

        # ---- 策略 ----
        self.policies = PoliciesCommands(rmq_client, default_vhost=vhost)
        self.operator_policies = OperatorPoliciesCommands(rmq_client, default_vhost=vhost)

        # ---- 参数 ----
        self.parameters = ParametersCommands(rmq_client, default_vhost=vhost)
        self.global_parameters = GlobalParametersCommands(rmq_client)

        # ---- 限制 ----
        self.vhost_limits = VhostLimitsCommands(rmq_client, default_vhost=vhost)
        self.user_limits = UserLimitsCommands(rmq_client)

        # ---- 节点 / 权限 ----
        self.nodes = NodesCommands(rmq_client)
        self.permissions = PermissionsCommands(rmq_client)

        # ---- 运维工具 ----
        self.definitions = DefinitionsCommands(rmq_client)
        self.health_check = HealthCheckCommands(rmq_client)
        self.feature_flags = FeatureFlagsCommands(rmq_client)
        self.rebalance = RebalanceCommands(rmq_client)

        self._client = rmq_client
        self._config_path = profile

    def clusters(self, format: str = "table"):
        """列出配置文件中所有可用的 RabbitMQ 集群

        Args:
            format: 输出��式，table 或 json（默认 table）
        """
        clusters = load_config(self._config_path)
        if not clusters:
            from rich.console import Console
            Console().print(
                f"[yellow]未找到任何集群配置，配置文件路径: {DEFAULT_CONFIG_PATH}[/yellow]"
            )
            return

        if format == "json":
            # 隐藏密码后输出
            safe = []
            for c in clusters:
                row = dict(c)
                if "password" in row:
                    row["password"] = "***"
                safe.append(row)
            print_json(safe)
        else:
            _print_clusters(clusters)

    def overview(self, format: str = "table"):
        """显示集群概览信息

        Args:
            format: 输出格式，table 或 json（默认 table）
        """
        data = self._client.get("/overview")
        if format == "json":
            print_json(data)
        else:
            columns = [
                "rabbitmq_version",
                "cluster_name",
                "erlang_version",
                "erlang_full_version",
            ]
            print_table([data], columns=columns)


def main():
    """CLI 程序入口"""
    fire.Fire(RmqAdm)


if __name__ == "__main__":
    main()
