# Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
# MindIE is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         `http://license.coscl.org.cn/MulanPSL2`
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.

from abc import ABC, abstractmethod

from olc.bean.match_wrapper import MatchWrapper
from olc.bean.olc_config_rule import FlowPolicy


class Limit(ABC):
    @abstractmethod
    def get_match_wrapper(self) -> MatchWrapper[FlowPolicy]:
        """
            获取该限速器的匹配规则
        :return:
        """
        pass

    # =========== 同步接口 =============
    @abstractmethod
    def try_acquire(self, token_number: int) -> bool:
        """
            尝试获取令牌
        :param token_number: 获取令牌数目
        :return: 是否成功
        """
        pass

    @abstractmethod
    def pre_check(self, token_number: int) -> bool:
        """
            提前检查
        :param token_number:
        :return:
        """
        pass

    @abstractmethod
    def roll_back(self, token_number: int):
        """
            回滚令牌
        :param token_number:
        :return:
        """
        pass

    @abstractmethod
    def dec_token(self, token_number: int):
        """
           强制扣减一定数目令牌, 不足的直接扣减至0, 负数为增加
        :param token_number:
        :return:
        """
        pass

    # ========= async_* 默认委托 =========
    #
    # 设计原则:
    # - 单机限流器(纯 CPU 算法)零改动即可在 async 路径下安全使用
    # - 集群限流器(含 IO)必须在子类显式覆盖这些方法,避免阻塞事件循环
    # =========== 异步接口 =============
    async def async_try_acquire(self, token_number: int) -> bool:
        """默认实现:直接代理同步 try_acquire。
           若子类实现含阻塞 I/O,必须显式覆盖此方法。
        """
        return self.try_acquire(token_number)

    async def async_pre_check(self, token_number: int) -> bool:
        """默认实现:直接代理同步 try_acquire。
           若子类实现含阻塞 I/O,必须显式覆盖此方法。
        """
        return self.pre_check(token_number)

    async def async_roll_back(self, token_number: int):
        """默认实现:直接代理同步 try_acquire。
           若子类实现含阻塞 I/O,必须显式覆盖此方法。
        """
        self.roll_back(token_number)

    async def async_dec_token(self, token_number: int):
        """默认实现:直接代理同步 try_acquire。
           若子类实现含阻塞 I/O,必须显式覆盖此方法。
        """
        self.dec_token(token_number)