# -*- coding: utf-8 -*-

"""Decorators for counting function call invocations."""

from functools import update_wrapper
from typing import Any, Callable


# pylint: disable=too-few-public-methods
class _CountWrapper:
    """It provides the mechanism to count invocations -- class decorator"""

    def __init__(self, fcn: Callable) -> None:
        update_wrapper(self, fcn)
        self.calls_number = 0
        self.fcn = fcn

    def __call__(self, *args: Any, **kwargs: Any) -> Any:
        self.calls_number += 1
        return self.fcn(*args, **kwargs)


def count_calls(fcn: Callable) -> _CountWrapper:
    """
    It provides the mechanism to count invocations...

    :param fcn: The function being decorated.
    :type fcn: Callable
    :return: The wrapped function with calls_number attribute.
    :rtype: _CountWrapper
    """
    return _CountWrapper(fcn)
