from typing import Optional
from datetime import datetime
from uuid import UUID
from abc import abstractmethod

import lqs.interface.dsm.models as models
from lqs.interface.base.list import ListInterface as BaseListInterface


class ListInterface(BaseListInterface):
    @abstractmethod
    def _announcement(self, **kwargs) -> models.AnnouncementListResponse:
        pass

    def announcement(
        self,
        id: Optional[UUID] = None,
        include_count: Optional[bool] = True,
        offset: Optional[int] = 0,
        limit: Optional[int] = 100,
        order: Optional[str] = "created_at",
        sort: Optional[str] = "ASC",
        datastore_id: Optional[UUID] = None,
        subject: Optional[str] = None,
        subject_like: Optional[str] = None,
        content: Optional[str] = None,
        content_like: Optional[str] = None,
        context: Optional[dict] = None,
        status: Optional[str] = None,
        status_like: Optional[str] = None,
        starts_at_gt: Optional[int] = None,
        starts_at_lt: Optional[datetime] = None,
        starts_at_gte: Optional[datetime] = None,
        starts_at_lte: Optional[datetime] = None,
        ends_at_gt: Optional[datetime] = None,
        ends_at_lt: Optional[datetime] = None,
        ends_at_gte: Optional[datetime] = None,
        ends_at_lte: Optional[datetime] = None,
        created_by: Optional[UUID] = None,
        updated_by: Optional[UUID] = None,
        deleted_by: Optional[UUID] = None,
        updated_by_null: Optional[bool] = None,
        deleted_by_null: Optional[bool] = None,
        updated_at_null: Optional[bool] = None,
        deleted_at_null: Optional[bool] = None,
        created_at_lte: Optional[datetime] = None,
        updated_at_lte: Optional[datetime] = None,
        deleted_at_lte: Optional[datetime] = None,
        created_at_gte: Optional[datetime] = None,
        updated_at_gte: Optional[datetime] = None,
        deleted_at_gte: Optional[datetime] = None,
    ):
        return self._announcement(
            id=id,
            include_count=include_count,
            offset=offset,
            limit=limit,
            order=order,
            sort=sort,
            datastore_id=datastore_id,
            subject=subject,
            subject_like=subject_like,
            content=content,
            content_like=content_like,
            context=context,
            status=status,
            status_like=status_like,
            starts_at_gt=starts_at_gt,
            starts_at_lt=starts_at_lt,
            starts_at_gte=starts_at_gte,
            starts_at_lte=starts_at_lte,
            ends_at_gt=ends_at_gt,
            ends_at_lt=ends_at_lt,
            ends_at_gte=ends_at_gte,
            ends_at_lte=ends_at_lte,
            created_by=created_by,
            updated_by=updated_by,
            deleted_by=deleted_by,
            updated_by_null=updated_by_null,
            deleted_by_null=deleted_by_null,
            updated_at_null=updated_at_null,
            deleted_at_null=deleted_at_null,
            created_at_lte=created_at_lte,
            updated_at_lte=updated_at_lte,
            deleted_at_lte=deleted_at_lte,
            created_at_gte=created_at_gte,
            updated_at_gte=updated_at_gte,
            deleted_at_gte=deleted_at_gte,
        )

    def announcements(self, **kwargs):
        return self.announcement(**kwargs)

    @abstractmethod
    def _comment(self, **kwargs) -> models.CommentListResponse:
        pass

    def comment(
        self,
        id: Optional[UUID] = None,
        include_count: Optional[bool] = True,
        offset: Optional[int] = 0,
        limit: Optional[int] = 100,
        order: Optional[str] = "created_at",
        sort: Optional[str] = "ASC",
        user_id: Optional[UUID] = None,
        datastore_id: Optional[UUID] = None,
        resource_type: Optional[str] = None,
        resource_id: Optional[UUID] = None,
        subject: Optional[str] = None,
        subject_like: Optional[str] = None,
        content: Optional[str] = None,
        content_like: Optional[str] = None,
        context: Optional[dict] = None,
        status: Optional[str] = None,
        status_like: Optional[str] = None,
        created_by: Optional[UUID] = None,
        updated_by: Optional[UUID] = None,
        deleted_by: Optional[UUID] = None,
        updated_by_null: Optional[bool] = None,
        deleted_by_null: Optional[bool] = None,
        updated_at_null: Optional[bool] = None,
        deleted_at_null: Optional[bool] = None,
        created_at_lte: Optional[datetime] = None,
        updated_at_lte: Optional[datetime] = None,
        deleted_at_lte: Optional[datetime] = None,
        created_at_gte: Optional[datetime] = None,
        updated_at_gte: Optional[datetime] = None,
        deleted_at_gte: Optional[datetime] = None,
    ):
        return self._comment(
            id=id,
            include_count=include_count,
            offset=offset,
            limit=limit,
            order=order,
            sort=sort,
            user_id=user_id,
            datastore_id=datastore_id,
            resource_type=resource_type,
            resource_id=resource_id,
            subject=subject,
            subject_like=subject_like,
            content=content,
            content_like=content_like,
            context=context,
            status=status,
            status_like=status_like,
            created_by=created_by,
            updated_by=updated_by,
            deleted_by=deleted_by,
            updated_by_null=updated_by_null,
            deleted_by_null=deleted_by_null,
            updated_at_null=updated_at_null,
            deleted_at_null=deleted_at_null,
            created_at_lte=created_at_lte,
            updated_at_lte=updated_at_lte,
            deleted_at_lte=deleted_at_lte,
            created_at_gte=created_at_gte,
            updated_at_gte=updated_at_gte,
            deleted_at_gte=deleted_at_gte,
        )

    def comments(self, **kwargs):
        return self.comment(**kwargs)

    @abstractmethod
    def _configuration(self, **kwargs) -> models.ConfigurationListResponse:
        pass

    def configuration(
        self,
        id: Optional[UUID] = None,
        include_count: Optional[bool] = True,
        offset: Optional[int] = 0,
        limit: Optional[int] = 100,
        order: Optional[str] = "created_at",
        sort: Optional[str] = "ASC",
        value: Optional[dict] = None,
        name: Optional[str] = None,
        name_like: Optional[str] = None,
        note: Optional[str] = None,
        note_like: Optional[str] = None,
        default: Optional[bool] = None,
        disabled: Optional[bool] = None,
        created_by: Optional[UUID] = None,
        updated_by: Optional[UUID] = None,
        deleted_by: Optional[UUID] = None,
        updated_by_null: Optional[bool] = None,
        deleted_by_null: Optional[bool] = None,
        updated_at_null: Optional[bool] = None,
        deleted_at_null: Optional[bool] = None,
        created_at_lte: Optional[datetime] = None,
        updated_at_lte: Optional[datetime] = None,
        deleted_at_lte: Optional[datetime] = None,
        created_at_gte: Optional[datetime] = None,
        updated_at_gte: Optional[datetime] = None,
        deleted_at_gte: Optional[datetime] = None,
    ):
        return self._configuration(
            id=id,
            include_count=include_count,
            offset=offset,
            limit=limit,
            order=order,
            sort=sort,
            value=value,
            name=name,
            name_like=name_like,
            note=note,
            note_like=note_like,
            default=default,
            disabled=disabled,
            created_by=created_by,
            updated_by=updated_by,
            deleted_by=deleted_by,
            updated_by_null=updated_by_null,
            deleted_by_null=deleted_by_null,
            updated_at_null=updated_at_null,
            deleted_at_null=deleted_at_null,
            created_at_lte=created_at_lte,
            updated_at_lte=updated_at_lte,
            deleted_at_lte=deleted_at_lte,
            created_at_gte=created_at_gte,
            updated_at_gte=updated_at_gte,
            deleted_at_gte=deleted_at_gte,
        )

    def configurations(self, **kwargs):
        return self.configuration(**kwargs)

    @abstractmethod
    def _datastore(self, **kwargs) -> models.DataStoreListResponse:
        pass

    def datastore(
        self,
        id: Optional[UUID] = None,
        include_count: Optional[bool] = True,
        offset: Optional[int] = 0,
        limit: Optional[int] = 100,
        order: Optional[str] = "created_at",
        sort: Optional[str] = "ASC",
        name: Optional[str] = None,
        name_like: Optional[str] = None,
        owner_id: Optional[UUID] = None,
        created_by: Optional[UUID] = None,
        updated_by: Optional[UUID] = None,
        deleted_by: Optional[UUID] = None,
        updated_by_null: Optional[bool] = None,
        deleted_by_null: Optional[bool] = None,
        updated_at_null: Optional[bool] = None,
        deleted_at_null: Optional[bool] = None,
        created_at_lte: Optional[datetime] = None,
        updated_at_lte: Optional[datetime] = None,
        deleted_at_lte: Optional[datetime] = None,
        created_at_gte: Optional[datetime] = None,
        updated_at_gte: Optional[datetime] = None,
        deleted_at_gte: Optional[datetime] = None,
    ):
        return self._datastore(
            id=id,
            include_count=include_count,
            offset=offset,
            limit=limit,
            order=order,
            sort=sort,
            name=name,
            name_like=name_like,
            owner_id=owner_id,
            created_by=created_by,
            updated_by=updated_by,
            deleted_by=deleted_by,
            updated_by_null=updated_by_null,
            deleted_by_null=deleted_by_null,
            updated_at_null=updated_at_null,
            deleted_at_null=deleted_at_null,
            created_at_lte=created_at_lte,
            updated_at_lte=updated_at_lte,
            deleted_at_lte=deleted_at_lte,
            created_at_gte=created_at_gte,
            updated_at_gte=updated_at_gte,
            deleted_at_gte=deleted_at_gte,
        )

    def datastores(self, **kwargs):
        return self.datastore(**kwargs)

    @abstractmethod
    def _datastore_association(
        self, **kwargs
    ) -> models.DataStoreAssociationListResponse:
        pass

    def datastore_association(
        self,
        id: Optional[UUID] = None,
        include_count: Optional[bool] = True,
        offset: Optional[int] = 0,
        limit: Optional[int] = 100,
        order: Optional[str] = "created_at",
        sort: Optional[str] = "ASC",
        user_id: Optional[UUID] = None,
        datastore_id: Optional[UUID] = None,
        datastore_user_id: Optional[UUID] = None,
        manager: Optional[bool] = None,
        disabled: Optional[bool] = None,
        created_by: Optional[UUID] = None,
        updated_by: Optional[UUID] = None,
        deleted_by: Optional[UUID] = None,
        updated_by_null: Optional[bool] = None,
        deleted_by_null: Optional[bool] = None,
        updated_at_null: Optional[bool] = None,
        deleted_at_null: Optional[bool] = None,
        created_at_lte: Optional[datetime] = None,
        updated_at_lte: Optional[datetime] = None,
        deleted_at_lte: Optional[datetime] = None,
        created_at_gte: Optional[datetime] = None,
        updated_at_gte: Optional[datetime] = None,
        deleted_at_gte: Optional[datetime] = None,
    ):
        return self._datastore_association(
            id=id,
            include_count=include_count,
            user_id=user_id,
            datastore_id=datastore_id,
            datastore_user_id=datastore_user_id,
            manager=manager,
            disabled=disabled,
            offset=offset,
            limit=limit,
            order=order,
            sort=sort,
            created_by=created_by,
            updated_by=updated_by,
            deleted_by=deleted_by,
            updated_by_null=updated_by_null,
            deleted_by_null=deleted_by_null,
            updated_at_null=updated_at_null,
            deleted_at_null=deleted_at_null,
            created_at_lte=created_at_lte,
            updated_at_lte=updated_at_lte,
            deleted_at_lte=deleted_at_lte,
            created_at_gte=created_at_gte,
            updated_at_gte=updated_at_gte,
            deleted_at_gte=deleted_at_gte,
        )

    def datastore_associations(self, **kwargs):
        return self.datastore_association(**kwargs)

    @abstractmethod
    def _usage_tick(self, **kwargs) -> models.UsageTickListResponse:
        pass

    def usage_tick(
        self,
        timestamp: Optional[models.Int64] = None,
        datastore_id: Optional[UUID] = None,
        timestamp_gt: Optional[models.Int64] = None,
        timestamp_lt: Optional[models.Int64] = None,
        timestamp_gte: Optional[models.Int64] = None,
        timestamp_lte: Optional[models.Int64] = None,
        log_count_gt: Optional[int] = None,
        log_count_lt: Optional[int] = None,
        log_count_gte: Optional[int] = None,
        log_count_lte: Optional[int] = None,
        record_count_gt: Optional[int] = None,
        record_count_lt: Optional[int] = None,
        record_count_gte: Optional[int] = None,
        record_count_lte: Optional[int] = None,
        record_size_gt: Optional[int] = None,
        record_size_lt: Optional[int] = None,
        record_size_gte: Optional[int] = None,
        record_size_lte: Optional[int] = None,
        object_count_gt: Optional[int] = None,
        object_count_lt: Optional[int] = None,
        object_count_gte: Optional[int] = None,
        object_count_lte: Optional[int] = None,
        object_size_gt: Optional[int] = None,
        object_size_lt: Optional[int] = None,
        object_size_gte: Optional[int] = None,
        object_size_lte: Optional[int] = None,
        transfer_size_gt: Optional[int] = None,
        transfer_size_lt: Optional[int] = None,
        transfer_size_gte: Optional[int] = None,
        transfer_size_lte: Optional[int] = None,
        include_count: Optional[bool] = True,
        offset: Optional[int] = 0,
        limit: Optional[int] = 100,
        order: Optional[str] = "timestamp",
        sort: Optional[str] = "ASC",
        created_by: Optional[UUID] = None,
        updated_by: Optional[UUID] = None,
        deleted_by: Optional[UUID] = None,
        updated_by_null: Optional[bool] = None,
        deleted_by_null: Optional[bool] = None,
        updated_at_null: Optional[bool] = None,
        deleted_at_null: Optional[bool] = None,
        created_at_lte: Optional[datetime] = None,
        updated_at_lte: Optional[datetime] = None,
        deleted_at_lte: Optional[datetime] = None,
        created_at_gte: Optional[datetime] = None,
        updated_at_gte: Optional[datetime] = None,
        deleted_at_gte: Optional[datetime] = None,
    ):
        return self._usage_tick(
            timestamp=timestamp,
            datastore_id=datastore_id,
            timestamp_gt=timestamp_gt,
            timestamp_lt=timestamp_lt,
            timestamp_gte=timestamp_gte,
            timestamp_lte=timestamp_lte,
            log_count_gt=log_count_gt,
            log_count_lt=log_count_lt,
            log_count_gte=log_count_gte,
            log_count_lte=log_count_lte,
            record_count_gt=record_count_gt,
            record_count_lt=record_count_lt,
            record_count_gte=record_count_gte,
            record_count_lte=record_count_lte,
            record_size_gt=record_size_gt,
            record_size_lt=record_size_lt,
            record_size_gte=record_size_gte,
            record_size_lte=record_size_lte,
            object_count_gt=object_count_gt,
            object_count_lt=object_count_lt,
            object_count_gte=object_count_gte,
            object_count_lte=object_count_lte,
            object_size_gt=object_size_gt,
            object_size_lt=object_size_lt,
            object_size_gte=object_size_gte,
            object_size_lte=object_size_lte,
            transfer_size_gt=transfer_size_gt,
            transfer_size_lt=transfer_size_lt,
            transfer_size_gte=transfer_size_gte,
            transfer_size_lte=transfer_size_lte,
            include_count=include_count,
            offset=offset,
            limit=limit,
            order=order,
            sort=sort,
            created_by=created_by,
            updated_by=updated_by,
            deleted_by=deleted_by,
            updated_by_null=updated_by_null,
            deleted_by_null=deleted_by_null,
            updated_at_null=updated_at_null,
            deleted_at_null=deleted_at_null,
            created_at_lte=created_at_lte,
            updated_at_lte=updated_at_lte,
            deleted_at_lte=deleted_at_lte,
            created_at_gte=created_at_gte,
            updated_at_gte=updated_at_gte,
            deleted_at_gte=deleted_at_gte,
        )

    def usage_ticks(self, **kwargs):
        return self.usage_tick(**kwargs)
