"""
keys.py
This module defines key objects used in ActivityPub.
"""

from typing import ClassVar, override

from pydantic import ConfigDict, Field

from phederation.models.errors import BaseError
from phederation.models.objects import APObject
from phederation.utils.base import APDateTime


class ErrorMessageKeyNotFound(BaseError):
    message: str = "Key not found"
    description: str = "The key with the given id could not be found on the instance."


class ErrorMessageKeyRestricted(BaseError):
    message: str = "Key has restricted visibility."
    description: str = "The key with the given id has restricted visibility."


class APPublicKey(APObject):
    """ActivityPub public key class."""

    type: str = Field(default="Key", description="This is a key.")
    public_key_pem: str | None = Field(default=None, description="The PEM string of the public key.")
    created_at: APDateTime | None = Field(default=None, description="Created time")
    expires_at: APDateTime | None = Field(default=None, description="Expiry time")

    def is_expired(self, now: APDateTime):
        if self.expires_at and now > self.expires_at:
            return True
        else:
            return False

    model_config: ClassVar[ConfigDict] = ConfigDict(
        json_schema_extra={
            "examples": [
                {
                    "id": "https://example.org/keys/odhfsd-sdfsdf-sdrqwe434-adasdasd-12311eawed",
                    "type": "Key",
                    "publicKeyPem": "<pem string>",
                }
            ]
        }
    )

    @override
    def __str__(self):
        return str(self.id)


class APPrivateKey(APPublicKey):
    """ActivityPub private key class."""

    private_key_pem: str | None = Field(default=None, description="The PEM string of the private key.")

    model_config: ClassVar[ConfigDict] = ConfigDict(
        json_schema_extra={
            "examples": [
                {
                    "id": "https://example.org/keys/odhfsd-sdfsdf-sdrqwe434-adasdasd-12311eawed",
                    "type": "Key",
                    "publicKeyPem": "<pem string of public key>",
                    "privateKeyPem": "<pem string of private ky>",
                }
            ]
        }
    )

    @override
    def __str__(self):
        return str(self.id)
