from rest_framework.relations import Hyperlink

from assistance.models.model_knowledge_base_article import all_models

from core.lib.feature_not_used import FeatureNotUsed



class APICommonFields:
    """Test Cases for fields common to All API responses

    Must contain:
    - id
    - display_name
    - _urls
    - _urls._self
    """


    api_data: object
    """ API Response data """



    def test_api_field_exists_id(self):
        """ Test for existance of API Field

        id field must exist
        """

        assert 'id' in self.api_data


    def test_api_field_type_id(self):
        """ Test for type for API Field

        id field must be int
        """

        assert type(self.api_data['id']) is int


    def test_api_field_exists_display_name(self):
        """ Test for existance of API Field

        display_name field must exist
        """

        assert 'display_name' in self.api_data


    def test_api_field_type_display_name(self):
        """ Test for type for API Field

        display_name field must be str
        """

        assert type(self.api_data['display_name']) is str



    def test_api_field_exists_urls(self):
        """ Test for existance of API Field

        _urls field must exist
        """

        assert '_urls' in self.api_data


    def test_api_field_type_urls(self):
        """ Test for type for API Field

        _urls field must be str
        """

        assert type(self.api_data['_urls']) is dict


    def test_api_field_exists_urls_self(self):
        """ Test for existance of API Field

        _urls._self field must exist
        """

        assert '_self' in self.api_data['_urls']


    def test_api_field_type_urls_self(self):
        """ Test for type for API Field

        _urls._self field must be str
        """

        assert type(self.api_data['_urls']['_self']) is str



    # def test_api_field_exists_urls_notes(self):
    #     """ Test for existance of API Field

    #     _urls.notes field must exist
    #     """

    #     obj = getattr(self.item, 'get_url_kwargs_notes', None)

    #     if callable(obj):

    #         obj = obj()

    #     if(
    #         not str(self.model._meta.model_name).lower().endswith('notes')
    #         and obj is not FeatureNotUsed
    #     ):

    #         assert 'notes' in self.api_data['_urls']

    #     else:

    #         print('Test is n/a')

    #         assert True


    # def test_api_field_type_urls_notes(self):
    #     """ Test for type for API Field

    #     _urls._self field must be str
    #     """

    #     obj = getattr(self.item, 'get_url_kwargs_notes', None)

    #     if callable(obj):

    #         obj = obj()

    #     if(
    #         not str(self.model._meta.model_name).lower().endswith('notes')
    #         and obj is not FeatureNotUsed
    #     ):

    #         assert type(self.api_data['_urls']['notes']) is str

    #     else:

    #         print('Test is n/a')

    #         assert True



class APIModelFields(
    APICommonFields
):
    """Test Cases for fields common to All API Model responses

    Must contain:
    - id
    - display_name
    - _urls
    - _urls._self
    """


    api_data: object
    """ API Response data """


    def test_api_field_exists_model_notes(self):
        """ Test for existance of API Field

        model_notes field must exist
        """

        assert 'model_notes' in self.api_data


    def test_api_field_type_model_notes(self):
        """ Test for type for API Field

        model_notes field must be str
        """

        assert type(self.api_data['model_notes']) is str



    def test_api_field_exists_created(self):
        """ Test for existance of API Field

        created field must exist
        """

        assert 'created' in self.api_data


    def test_api_field_type_created(self):
        """ Test for type for API Field

        created field must be str
        """

        assert type(self.api_data['created']) is str



    def test_api_field_exists_modified(self):
        """ Test for existance of API Field

        modified field must exist
        """

        assert 'modified' in self.api_data


    def test_api_field_type_modified(self):
        """ Test for type for API Field

        modified field must be str
        """

        assert type(self.api_data['modified']) is str



class APITenancyObject(
    APIModelFields
):


    api_data: object
    """ API Response data """



    def test_api_field_exists_organization(self):
        """ Test for existance of API Field

        organization field must exist
        """

        assert 'organization' in self.api_data


    def test_api_field_type_organization(self):
        """ Test for type for API Field

        organization field must be dict
        """

        assert type(self.api_data['organization']) is dict



    def test_api_field_exists_organization_id(self):
        """ Test for existance of API Field

        organization.id field must exist
        """

        assert 'id' in self.api_data['organization']


    def test_api_field_type_organization_id(self):
        """ Test for type for API Field

        organization.id field must be dict
        """

        assert type(self.api_data['organization']['id']) is int


    def test_api_field_exists_organization_display_name(self):
        """ Test for existance of API Field

        organization.display_name field must exist
        """

        assert 'display_name' in self.api_data['organization']


    def test_api_field_type_organization_display_name(self):
        """ Test for type for API Field

        organization.display_name field must be str
        """

        assert type(self.api_data['organization']['display_name']) is str


    def test_api_field_exists_organization_url(self):
        """ Test for existance of API Field

        organization.url field must exist
        """

        assert 'url' in self.api_data['organization']


    def test_api_field_type_organization_url(self):
        """ Test for type for API Field

        organization.url field must be str
        """

        assert type(self.api_data['organization']['url']) is Hyperlink
