"""Simplifies interacting with an ActivityPub server / instance.

This is a minimal implementation only implementing some API calls. API
calls supported will likely be expanded over time. However, do not
expect a full or complete implementation of the ActivityPub API.
"""

import logging

from httpx import AsyncClient
from whenever import Instant

from minimal_activitypub import __display_name__
from minimal_activitypub import __version__
from minimal_activitypub._mixin_auth import _AuthMixin
from minimal_activitypub._mixin_credentials import _CredentialsMixin
from minimal_activitypub._mixin_request_helpers import _RequestHelpersMixin
from minimal_activitypub._mixin_statuses import _StatusesMixin
from minimal_activitypub._mixin_timelines import _TimelinesMixin
from minimal_activitypub.constants import INSTANCE_TYPE_MASTODON
from minimal_activitypub.constants import INSTANCE_TYPE_PLEROMA  # noqa: F401
from minimal_activitypub.constants import INSTANCE_TYPE_TAKAHE  # noqa: F401
from minimal_activitypub.constants import MAX_ATTACHMENTS_MASTODON
from minimal_activitypub.constants import MAX_ATTACHMENTS_PLEROMA  # noqa: F401
from minimal_activitypub.constants import MAX_ATTACHMENTS_TAKAHE  # noqa: F401
from minimal_activitypub.exceptions import ActivityPubError  # noqa: F401
from minimal_activitypub.exceptions import ApiError  # noqa: F401
from minimal_activitypub.exceptions import ClientError  # noqa: F401
from minimal_activitypub.exceptions import ConflictError  # noqa: F401
from minimal_activitypub.exceptions import ForbiddenError  # noqa: F401
from minimal_activitypub.exceptions import GoneError  # noqa: F401
from minimal_activitypub.exceptions import NetworkError  # noqa: F401
from minimal_activitypub.exceptions import NotFoundError  # noqa: F401
from minimal_activitypub.exceptions import RatelimitError  # noqa: F401
from minimal_activitypub.exceptions import ServerError  # noqa: F401
from minimal_activitypub.exceptions import UnauthorizedError  # noqa: F401
from minimal_activitypub.exceptions import UnprocessedError  # noqa: F401
from minimal_activitypub.types import ActivityPubClass

logger = logging.getLogger(__display_name__)


class ActivityPub(_RequestHelpersMixin, _CredentialsMixin, _TimelinesMixin, _StatusesMixin, _AuthMixin):
    """Simplifies interacting with an ActivityPub server / instance.

    This is a minimal implementation only implementing methods needed
    for the function of MastodonAmnesia
    """

    def __init__(
        self: ActivityPubClass,
        instance: str,
        client: AsyncClient,
        access_token: str | None = None,
        timeout: int | None = None,
    ) -> None:
        """Initialise ActivityPub instance with reasonable default values.

        :param instance: domain name or url to instance to connect to
        :param client: httpx AsyncClient to use for communicating with instance
        :param access_token: authentication token
        :param timeout: Optional number of seconds to wait for a response from the instance server.
            Defaults to None which equates to 120 seconds / 2 minutes timeout

        """
        self.instance = instance.rstrip("/")
        self.headers: list[tuple[str, str]] = []
        if access_token:
            self.headers.append(("Authorization", f"Bearer {access_token}"))
        self.client = client
        self.pagination: dict[str, dict[str, str | None]] = {
            "next": {"max_id": None, "min_id": None},
            "prev": {"max_id": None, "min_id": None},
        }
        self.timeout = timeout if timeout else 120
        self.instance_type = INSTANCE_TYPE_MASTODON  # default until determined otherwise with determine_instance_type()
        self.max_attachments = MAX_ATTACHMENTS_MASTODON
        self.max_att_size = 10000000
        self.supported_mime_types: list[str] = []
        self.max_status_len = 500
        self.ratelimit_limit = 300
        self.ratelimit_remaining = 300
        self.ratelimit_reset = Instant.now().py_datetime()
        logger.debug(
            "client_2_server.ActivityPub(instance=%s, client=%s, access_token=<redacted>)",
            instance,
            client,
        )
        logger.debug("client_2_server.ActivityPub() ... version=%s", __version__)
