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,
        note_like: Optional[str] = None,
        config_filter: Optional[str] = None,
        owner_id: Optional[UUID] = None,
        endpoint: Optional[str] = None,
        endpoint_like: Optional[str] = None,
        disabled: Optional[bool] = None,
        plan: Optional[str] = None,
        plan_like: Optional[str] = None,
        plan_null: Optional[bool] = None,
        record_count: 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,
        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,
            note_like=note_like,
            config_filter=config_filter,
            owner_id=owner_id,
            endpoint=endpoint,
            endpoint_like=endpoint_like,
            disabled=disabled,
            plan=plan,
            plan_like=plan_like,
            plan_null=plan_null,
            record_count=record_count,
            record_count_gt=record_count_gt,
            record_count_lt=record_count_lt,
            record_count_gte=record_count_gte,
            record_count_lte=record_count_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 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 _event(self, **kwargs) -> models.EventListResponse:
        pass

    def event(
        self,
        id: Optional[UUID] = None,
        previous_state: Optional[str] = None,
        current_state: Optional[str] = None,
        process_type: Optional[str] = None,
        resource_id: Optional[UUID] = None,
        workflow_id: Optional[UUID] = None,
        hook_id: Optional[UUID] = None,
        datastore_id: Optional[UUID] = None,
        datastore_endpoint: Optional[str] = None,
        include_count: Optional[bool] = True,
        offset: Optional[int] = 0,
        limit: Optional[int] = 100,
        order: Optional[str] = "created_at",
        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._event(
            id=id,
            previous_state=previous_state,
            current_state=current_state,
            process_type=process_type,
            resource_id=resource_id,
            workflow_id=workflow_id,
            hook_id=hook_id,
            datastore_id=datastore_id,
            datastore_endpoint=datastore_endpoint,
            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 events(self, **kwargs):
        return self.event(**kwargs)

    @abstractmethod
    def _job(self, **kwargs) -> models.JobListResponse:
        pass

    def job(
        self,
        id: Optional[UUID] = None,
        event_id: Optional[UUID] = None,
        process_type: Optional[str] = None,
        resource_id: Optional[UUID] = None,
        datastore_id: Optional[UUID] = None,
        datastore_endpoint: Optional[str] = None,
        state: Optional[str] = None,
        include_count: Optional[bool] = True,
        error_filter: Optional[str] = None,
        offset: Optional[int] = 0,
        limit: Optional[int] = 100,
        order: Optional[str] = "created_at",
        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._job(
            id=id,
            event_id=event_id,
            process_type=process_type,
            resource_id=resource_id,
            datastore_id=datastore_id,
            datastore_endpoint=datastore_endpoint,
            state=state,
            include_count=include_count,
            error_filter=error_filter,
            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 jobs(self, **kwargs):
        return self.job(**kwargs)

    @abstractmethod
    def _usage_record(self, **kwargs) -> models.UsageRecordListResponse:
        pass

    def usage_record(
        self,
        timestamp: Optional[models.Int64] = None,
        datastore_id: Optional[UUID] = None,
        user_id: Optional[UUID] = None,
        datastore_id_null: Optional[bool] = None,
        user_id_null: Optional[bool] = 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,
        duration: Optional[models.Int64] = None,
        duration_gt: Optional[models.Int64] = None,
        duration_lt: Optional[models.Int64] = None,
        duration_gte: Optional[models.Int64] = None,
        duration_lte: Optional[models.Int64] = None,
        category: Optional[str] = None,
        usage_data_filter: Optional[str] = None,
        frequency: Optional[float] = 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_record(
            timestamp=timestamp,
            datastore_id=datastore_id,
            user_id=user_id,
            datastore_id_null=datastore_id_null,
            user_id_null=user_id_null,
            timestamp_gt=timestamp_gt,
            timestamp_lt=timestamp_lt,
            timestamp_gte=timestamp_gte,
            timestamp_lte=timestamp_lte,
            duration=duration,
            duration_gt=duration_gt,
            duration_lt=duration_lt,
            duration_gte=duration_gte,
            duration_lte=duration_lte,
            category=category,
            usage_data_filter=usage_data_filter,
            frequency=frequency,
            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_records(self, **kwargs):
        return self.usage_record(**kwargs)

    @abstractmethod
    def _user(self, **kwargs) -> models.UserListResponse:
        pass

    def user(
        self,
        username: Optional[str] = None,
        username_like: Optional[str] = None,
        role_id: Optional[UUID] = None,
        managed: Optional[bool] = None,
        disabled: Optional[bool] = None,
        admin: Optional[bool] = None,
        external_id: Optional[str] = None,
        context_filter: Optional[str] = None,
        first_name: Optional[str] = None,
        first_name_like: Optional[str] = None,
        last_name: Optional[str] = None,
        last_name_like: Optional[str] = None,
        phone: Optional[str] = None,
        phone_like: Optional[str] = None,
        company: Optional[str] = None,
        company_like: Optional[str] = None,
        job_title: Optional[str] = None,
        job_title_like: Optional[str] = None,
        language: Optional[str] = None,
        language_like: Optional[str] = None,
        time_zone: Optional[str] = None,
        time_zone_like: Optional[str] = None,
        address_line_1: Optional[str] = None,
        address_line_1_like: Optional[str] = None,
        address_line_2: Optional[str] = None,
        address_line_2_like: Optional[str] = None,
        city: Optional[str] = None,
        city_like: Optional[str] = None,
        state: Optional[str] = None,
        state_like: Optional[str] = None,
        postal_code: Optional[str] = None,
        postal_code_like: Optional[str] = None,
        country: Optional[str] = None,
        country_like: Optional[str] = None,
        include_count: Optional[bool] = True,
        offset: Optional[int] = 0,
        limit: Optional[int] = 100,
        order: Optional[str] = "created_at",
        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,
    ) -> models.UserListResponse:
        return self._user(
            username=username,
            username_like=username_like,
            role_id=role_id,
            managed=managed,
            disabled=disabled,
            admin=admin,
            external_id=external_id,
            context_filter=context_filter,
            first_name=first_name,
            first_name_like=first_name_like,
            last_name=last_name,
            last_name_like=last_name_like,
            phone=phone,
            phone_like=phone_like,
            company=company,
            company_like=company_like,
            job_title=job_title,
            job_title_like=job_title_like,
            language=language,
            language_like=language_like,
            time_zone=time_zone,
            time_zone_like=time_zone_like,
            address_line_1=address_line_1,
            address_line_1_like=address_line_1_like,
            address_line_2=address_line_2,
            address_line_2_like=address_line_2_like,
            city=city,
            city_like=city_like,
            state=state,
            state_like=state_like,
            postal_code=postal_code,
            postal_code_like=postal_code_like,
            country=country,
            country_like=country_like,
            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 users(self, **kwargs) -> models.UserListResponse:
        return self.user(**kwargs)
