"""
    Agilicus API

    Agilicus is API-first. Modern software is controlled by other software, is open, is available for you to use the way you want, securely, simply.  The OpenAPI Specification in YAML format is available on [www](https://www.agilicus.com/www/api/agilicus-openapi.yaml) for importing to other tools.  A rendered, online viewable and usable version of this specification is available at [api](https://www.agilicus.com/api). You may try the API inline directly in the web page. To do so, first obtain an Authentication Token (the simplest way is to install the Python SDK, and then run `agilicus-cli --issuer https://MYISSUER get-token`). You will need an org-id for most calls (and can obtain from `agilicus-cli --issuer https://MYISSUER list-orgs`). The `MYISSUER` will typically be `auth.MYDOMAIN`, and you will see it as you sign-in to the administrative UI.  This API releases on Bearer-Token authentication. To obtain a valid bearer token you will need to Authenticate to an Issuer with OpenID Connect (a superset of OAUTH2).  Your \"issuer\" will look like https://auth.MYDOMAIN. For example, when you signed-up, if you said \"use my own domain name\" and assigned a CNAME of cloud.example.com, then your issuer would be https://auth.cloud.example.com.  If you selected \"use an Agilicus supplied domain name\", your issuer would look like https://auth.myorg.agilicus.cloud.  For test purposes you can use our [Python SDK](https://pypi.org/project/agilicus/) and run `agilicus-cli --issuer https://auth.MYDOMAIN get-token`.  This API may be used in any language runtime that supports OpenAPI 3.0, or, you may use our [Python SDK](https://pypi.org/project/agilicus/), our [Typescript SDK](https://www.npmjs.com/package/@agilicus/angular), or our [Golang SDK](https://git.agilicus.com/pub/sdk-go).  100% of the activities in our system our API-driven, from our web-admin, through our progressive web applications, to all internals: there is nothing that is not accessible.  For more information, see [developer resources](https://www.agilicus.com/developer).   # noqa: E501

    The version of the OpenAPI document: 2024.05.09
    Contact: dev@agilicus.com
    Generated by: https://openapi-generator.tech
"""


import re  # noqa: F401
import sys  # noqa: F401

from agilicus_api.model_utils import (  # noqa: F401
    ApiTypeError,
    ModelComposed,
    ModelNormal,
    ModelSimple,
    cached_property,
    change_keys_js_to_python,
    convert_js_args_to_python_args,
    date,
    datetime,
    file_type,
    none_type,
    validate_get_composed_info,
)
from ..model_utils import OpenApiModel
from agilicus_api.exceptions import ApiAttributeError


def lazy_import():
    from agilicus_api.model.alternate_mode_setting import AlternateModeSetting
    from agilicus_api.model.application_assignment import ApplicationAssignment
    from agilicus_api.model.application_monitoring_config import ApplicationMonitoringConfig
    from agilicus_api.model.application_state_selector import ApplicationStateSelector
    from agilicus_api.model.definition import Definition
    from agilicus_api.model.display_info import DisplayInfo
    from agilicus_api.model.environment import Environment
    from agilicus_api.model.k8s_slug import K8sSlug
    from agilicus_api.model.role_list import RoleList
    from agilicus_api.model.roles_config import RolesConfig
    from agilicus_api.model.rules_config import RulesConfig
    from agilicus_api.model.workload_configuration import WorkloadConfiguration
    globals()['AlternateModeSetting'] = AlternateModeSetting
    globals()['ApplicationAssignment'] = ApplicationAssignment
    globals()['ApplicationMonitoringConfig'] = ApplicationMonitoringConfig
    globals()['ApplicationStateSelector'] = ApplicationStateSelector
    globals()['Definition'] = Definition
    globals()['DisplayInfo'] = DisplayInfo
    globals()['Environment'] = Environment
    globals()['K8sSlug'] = K8sSlug
    globals()['RoleList'] = RoleList
    globals()['RolesConfig'] = RolesConfig
    globals()['RulesConfig'] = RulesConfig
    globals()['WorkloadConfiguration'] = WorkloadConfiguration


class Application(ModelNormal):
    """NOTE: This class is auto generated by OpenAPI Generator.
    Ref: https://openapi-generator.tech

    Do not edit the class manually.

    Attributes:
      allowed_values (dict): The key is the tuple path to the attribute
          and the for var_name this is (var_name,). The value is a dict
          with a capitalized key describing the allowed value and an allowed
          value. These dicts store the allowed enum values.
      attribute_map (dict): The key is attribute name
          and the value is json key in definition.
      discriminator_value_class_map (dict): A dict to go from the discriminator
          variable value to the discriminator class name.
      validations (dict): The key is the tuple path to the attribute
          and the for var_name this is (var_name,). The value is a dict
          that stores validations for max_length, min_length, max_items,
          min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum,
          inclusive_minimum, and regex.
      additional_properties_type (tuple): A tuple of classes accepted
          as additional properties values.
    """

    allowed_values = {
        ('image_credentials_type',): {
            'BASIC_AUTH': "basic_auth",
            'TOKEN': "token",
        },
        ('published',): {
            'NO': "no",
            'PUBLIC': "public",
        },
        ('location',): {
            'HOSTED': "hosted",
            'EXTERNAL': "external",
        },
        ('application_type',): {
            'USER_DEFINED': "user_defined",
            'INTERNAL': "internal",
        },
    }

    validations = {
        ('name',): {
            'max_length': 63,
            'min_length': 1,
            'regex': {
                'pattern': r'^[a-zA-Z0-9-:]+$',  # noqa: E501
            },
        },
        ('category',): {
            'max_length': 100,
            'min_length': 1,
        },
        ('org_id',): {
            'max_length': 40,
            'min_length': 1,
        },
        ('image_username',): {
            'max_length': 100,
            'min_length': 1,
        },
        ('image_password',): {
            'max_length': 100,
            'min_length': 1,
        },
        ('contact_email',): {
            'max_length': 100,
        },
        ('default_role_id',): {
            'max_length': 40,
        },
        ('default_role_name',): {
            'max_length': 100,
            'min_length': 1,
        },
        ('icon_url',): {
            'max_length': 1024,
        },
        ('service_account_id',): {
            'max_length': 40,
            'min_length': 1,
        },
    }

    @property
    def created(self):
       return self.get("created")

    @created.setter
    def created(self, new_value):
       self.created = new_value

    @property
    def id(self):
       return self.get("id")

    @id.setter
    def id(self, new_value):
       self.id = new_value

    @property
    def parent_id(self):
       return self.get("parent_id")

    @parent_id.setter
    def parent_id(self, new_value):
       self.parent_id = new_value

    @property
    def name(self):
       return self.get("name")

    @name.setter
    def name(self, new_value):
       self.name = new_value

    @property
    def description(self):
       return self.get("description")

    @description.setter
    def description(self, new_value):
       self.description = new_value

    @property
    def category(self):
       return self.get("category")

    @category.setter
    def category(self, new_value):
       self.category = new_value

    @property
    def image(self):
       return self.get("image")

    @image.setter
    def image(self, new_value):
       self.image = new_value

    @property
    def image_username(self):
       return self.get("image_username")

    @image_username.setter
    def image_username(self, new_value):
       self.image_username = new_value

    @property
    def image_password(self):
       return self.get("image_password")

    @image_password.setter
    def image_password(self, new_value):
       self.image_password = new_value

    @property
    def image_credentials_type(self):
       return self.get("image_credentials_type")

    @image_credentials_type.setter
    def image_credentials_type(self, new_value):
       self.image_credentials_type = new_value

    @property
    def environments(self):
       return self.get("environments")

    @environments.setter
    def environments(self, new_value):
       self.environments = new_value

    @property
    def org_id(self):
       return self.get("org_id")

    @org_id.setter
    def org_id(self, new_value):
       self.org_id = new_value

    @property
    def contact_email(self):
       return self.get("contact_email")

    @contact_email.setter
    def contact_email(self, new_value):
       self.contact_email = new_value

    @property
    def monitoring_config(self):
       return self.get("monitoring_config")

    @monitoring_config.setter
    def monitoring_config(self, new_value):
       self.monitoring_config = new_value

    @property
    def port(self):
       return self.get("port")

    @port.setter
    def port(self, new_value):
       self.port = new_value

    @property
    def healthcheck_uri(self):
       return self.get("healthcheck_uri")

    @healthcheck_uri.setter
    def healthcheck_uri(self, new_value):
       self.healthcheck_uri = new_value

    @property
    def roles(self):
       return self.get("roles")

    @roles.setter
    def roles(self, new_value):
       self.roles = new_value

    @property
    def roles_config(self):
       return self.get("roles_config")

    @roles_config.setter
    def roles_config(self, new_value):
       self.roles_config = new_value

    @property
    def rules_config(self):
       return self.get("rules_config")

    @rules_config.setter
    def rules_config(self, new_value):
       self.rules_config = new_value

    @property
    def definitions(self):
       return self.get("definitions")

    @definitions.setter
    def definitions(self, new_value):
       self.definitions = new_value

    @property
    def assignments(self):
       return self.get("assignments")

    @assignments.setter
    def assignments(self, new_value):
       self.assignments = new_value

    @property
    def owned(self):
       return self.get("owned")

    @owned.setter
    def owned(self, new_value):
       self.owned = new_value

    @property
    def maintained(self):
       return self.get("maintained")

    @maintained.setter
    def maintained(self, new_value):
       self.maintained = new_value

    @property
    def assigned(self):
       return self.get("assigned")

    @assigned.setter
    def assigned(self, new_value):
       self.assigned = new_value

    @property
    def published(self):
       return self.get("published")

    @published.setter
    def published(self, new_value):
       self.published = new_value

    @property
    def default_role_id(self):
       return self.get("default_role_id")

    @default_role_id.setter
    def default_role_id(self, new_value):
       self.default_role_id = new_value

    @property
    def default_role_name(self):
       return self.get("default_role_name")

    @default_role_name.setter
    def default_role_name(self, new_value):
       self.default_role_name = new_value

    @property
    def icon_url(self):
       return self.get("icon_url")

    @icon_url.setter
    def icon_url(self, new_value):
       self.icon_url = new_value

    @property
    def display_info(self):
       return self.get("display_info")

    @display_info.setter
    def display_info(self, new_value):
       self.display_info = new_value

    @property
    def updated(self):
       return self.get("updated")

    @updated.setter
    def updated(self, new_value):
       self.updated = new_value

    @property
    def location(self):
       return self.get("location")

    @location.setter
    def location(self, new_value):
       self.location = new_value

    @property
    def service_account_id(self):
       return self.get("service_account_id")

    @service_account_id.setter
    def service_account_id(self, new_value):
       self.service_account_id = new_value

    @property
    def service_account_required(self):
       return self.get("service_account_required")

    @service_account_required.setter
    def service_account_required(self, new_value):
       self.service_account_required = new_value

    @property
    def application_type(self):
       return self.get("application_type")

    @application_type.setter
    def application_type(self, new_value):
       self.application_type = new_value

    @property
    def name_slug(self):
       return self.get("name_slug")

    @name_slug.setter
    def name_slug(self, new_value):
       self.name_slug = new_value

    @property
    def workload_config(self):
       return self.get("workload_config")

    @workload_config.setter
    def workload_config(self, new_value):
       self.workload_config = new_value

    @property
    def admin_state(self):
       return self.get("admin_state")

    @admin_state.setter
    def admin_state(self, new_value):
       self.admin_state = new_value

    @property
    def alternate_mode_setting(self):
       return self.get("alternate_mode_setting")

    @alternate_mode_setting.setter
    def alternate_mode_setting(self, new_value):
       self.alternate_mode_setting = new_value

    @property
    def launchers(self):
       return self.get("launchers")

    @launchers.setter
    def launchers(self, new_value):
       self.launchers = new_value

    @cached_property
    def additional_properties_type():
        """
        This must be a method because a model may have properties that are
        of type self, this must run after the class is loaded
        """
        lazy_import()
        return (bool, date, datetime, dict, float, int, list, str, none_type,)  # noqa: E501

    _nullable = False

    @cached_property
    def openapi_types():
        """
        This must be a method because a model may have properties that are
        of type self, this must run after the class is loaded

        Returns
            openapi_types (dict): The key is attribute name
                and the value is attribute type.
        """
        lazy_import()
        return {
            'name': (str,),  # noqa: E501
            'category': (str,),  # noqa: E501
            'org_id': (str,),  # noqa: E501
            'created': (datetime,),  # noqa: E501
            'id': (str,),  # noqa: E501
            'parent_id': (str,),  # noqa: E501
            'description': (str,),  # noqa: E501
            'image': (str,),  # noqa: E501
            'image_username': (str,),  # noqa: E501
            'image_password': (str,),  # noqa: E501
            'image_credentials_type': (str,),  # noqa: E501
            'environments': ([Environment],),  # noqa: E501
            'contact_email': (str,),  # noqa: E501
            'monitoring_config': (ApplicationMonitoringConfig,),  # noqa: E501
            'port': (int,),  # noqa: E501
            'healthcheck_uri': (str,),  # noqa: E501
            'roles': (RoleList,),  # noqa: E501
            'roles_config': (RolesConfig,),  # noqa: E501
            'rules_config': (RulesConfig,),  # noqa: E501
            'definitions': ([Definition],),  # noqa: E501
            'assignments': ([ApplicationAssignment],),  # noqa: E501
            'owned': (bool,),  # noqa: E501
            'maintained': (bool,),  # noqa: E501
            'assigned': (bool,),  # noqa: E501
            'published': (str,),  # noqa: E501
            'default_role_id': (str, none_type,),  # noqa: E501
            'default_role_name': (str, none_type,),  # noqa: E501
            'icon_url': (str,),  # noqa: E501
            'display_info': (DisplayInfo,),  # noqa: E501
            'updated': (datetime,),  # noqa: E501
            'location': (str,),  # noqa: E501
            'service_account_id': (str,),  # noqa: E501
            'service_account_required': (bool,),  # noqa: E501
            'application_type': (str,),  # noqa: E501
            'name_slug': (K8sSlug,),  # noqa: E501
            'workload_config': (WorkloadConfiguration,),  # noqa: E501
            'admin_state': (ApplicationStateSelector,),  # noqa: E501
            'alternate_mode_setting': (AlternateModeSetting,),  # noqa: E501
            'launchers': ([str],),  # noqa: E501
        }

    @cached_property
    def discriminator():
        return None



    attribute_map = {
        'name': 'name',  # noqa: E501
        'category': 'category',  # noqa: E501
        'org_id': 'org_id',  # noqa: E501
        'created': 'created',  # noqa: E501
        'id': 'id',  # noqa: E501
        'parent_id': 'parent_id',  # noqa: E501
        'description': 'description',  # noqa: E501
        'image': 'image',  # noqa: E501
        'image_username': 'image_username',  # noqa: E501
        'image_password': 'image_password',  # noqa: E501
        'image_credentials_type': 'image_credentials_type',  # noqa: E501
        'environments': 'environments',  # noqa: E501
        'contact_email': 'contact_email',  # noqa: E501
        'monitoring_config': 'monitoring_config',  # noqa: E501
        'port': 'port',  # noqa: E501
        'healthcheck_uri': 'healthcheck_uri',  # noqa: E501
        'roles': 'roles',  # noqa: E501
        'roles_config': 'roles_config',  # noqa: E501
        'rules_config': 'rules_config',  # noqa: E501
        'definitions': 'definitions',  # noqa: E501
        'assignments': 'assignments',  # noqa: E501
        'owned': 'owned',  # noqa: E501
        'maintained': 'maintained',  # noqa: E501
        'assigned': 'assigned',  # noqa: E501
        'published': 'published',  # noqa: E501
        'default_role_id': 'default_role_id',  # noqa: E501
        'default_role_name': 'default_role_name',  # noqa: E501
        'icon_url': 'icon_url',  # noqa: E501
        'display_info': 'display_info',  # noqa: E501
        'updated': 'updated',  # noqa: E501
        'location': 'location',  # noqa: E501
        'service_account_id': 'service_account_id',  # noqa: E501
        'service_account_required': 'service_account_required',  # noqa: E501
        'application_type': 'application_type',  # noqa: E501
        'name_slug': 'name_slug',  # noqa: E501
        'workload_config': 'workload_config',  # noqa: E501
        'admin_state': 'admin_state',  # noqa: E501
        'alternate_mode_setting': 'alternate_mode_setting',  # noqa: E501
        'launchers': 'launchers',  # noqa: E501
    }

    read_only_vars = {
        'created',  # noqa: E501
        'id',  # noqa: E501
        'parent_id',  # noqa: E501
        'default_role_name',  # noqa: E501
        'updated',  # noqa: E501
        'service_account_id',  # noqa: E501
    }

    _composed_schemas = {}

    @classmethod
    @convert_js_args_to_python_args
    def _from_openapi_data(cls, name, category, org_id, *args, **kwargs):  # noqa: E501
        """Application - a model defined in OpenAPI

        Args:
            name (str): application name
            category (str): application category
            org_id (str): organisation id

        Keyword Args:
            _check_type (bool): if True, values for parameters in openapi_types
                                will be type checked and a TypeError will be
                                raised if the wrong type is input.
                                Defaults to True
            _path_to_item (tuple/list): This is a list of keys or values to
                                drill down to the model in received_data
                                when deserializing a response
            _spec_property_naming (bool): True if the variable names in the input data
                                are serialized names, as specified in the OpenAPI document.
                                False if the variable names in the input data
                                are pythonic names, e.g. snake case (default)
            _configuration (Configuration): the instance to use when
                                deserializing a file_type parameter.
                                If passed, type conversion is attempted
                                If omitted no type conversion is done.
            _visited_composed_classes (tuple): This stores a tuple of
                                classes that we have traveled through so that
                                if we see that class again we will not use its
                                discriminator again.
                                When traveling through a discriminator, the
                                composed schema that is
                                is traveled through is added to this set.
                                For example if Animal has a discriminator
                                petType and we pass in "Dog", and the class Dog
                                allOf includes Animal, we move through Animal
                                once using the discriminator, and pick Dog.
                                Then in Dog, we will make an instance of the
                                Animal class but this time we won't travel
                                through its discriminator because we passed in
                                _visited_composed_classes = (Animal,)
            created (datetime): Creation time. [optional]  # noqa: E501
            id (str): application service id. [optional]  # noqa: E501
            parent_id (str): For inheritance, defines the parent id.. [optional]  # noqa: E501
            description (str): Application description text. [optional]  # noqa: E501
            image (str): image registry path and name. [optional]  # noqa: E501
            image_username (str): registry username. [optional]  # noqa: E501
            image_password (str): registry password. [optional]  # noqa: E501
            image_credentials_type (str): type of credentials for image. [optional]  # noqa: E501
            environments ([Environment]): List of environments. [optional]  # noqa: E501
            contact_email (str): Administrator contact email. [optional]  # noqa: E501
            monitoring_config (ApplicationMonitoringConfig): [optional]  # noqa: E501
            port (int): The transport layer port the application listens on for requests. E.g. if the application listens for HTTP requests on the standard port, port 80, set this to 80. . [optional]  # noqa: E501
            healthcheck_uri (str): health check URI. [optional]  # noqa: E501
            roles (RoleList): [optional]  # noqa: E501
            roles_config (RolesConfig): [optional]  # noqa: E501
            rules_config (RulesConfig): [optional]  # noqa: E501
            definitions ([Definition]): List of definitions. [optional]  # noqa: E501
            assignments ([ApplicationAssignment]): Controls the Organisations which have access to Environments of this Application. . [optional]  # noqa: E501
            owned (bool): Whether this Application is owned by the provided organisation. . [optional]  # noqa: E501
            maintained (bool): Whether this Application has an Environment maintained by the provided organisation. . [optional]  # noqa: E501
            assigned (bool): Whether an Environment is assigned to this Application. . [optional]  # noqa: E501
            published (str): Whether or not this Application is published, and if so, how. An application that has been published somewhere will have high level details about it visible (through apis intended to expose published applications), such as its name and description. The enum values mean the following:  - no: This application is not published. It will only be visibile to users with       permission to access the application, or to administrators.  - public: This application is published to the public catalogue. Any user who       can request access to the organisation will see high level details about this       application. . [optional] if omitted the server will use the default value of "no"  # noqa: E501
            default_role_id (str, none_type): The id of the default role to use for this application. This role will be assigned to users granted access to this application by default, unless overridden. This value must point to a valid Role for this application. A string of length 0 will clear out the default role.. [optional]  # noqa: E501
            default_role_name (str, none_type): The name of the default role. Does not change which role is used. Provided for convenience. . [optional]  # noqa: E501
            icon_url (str): A url pointing to an icon representing this application. . [optional]  # noqa: E501
            display_info (DisplayInfo): [optional]  # noqa: E501
            updated (datetime): Update time. [optional]  # noqa: E501
            location (str): Where the application runs. Applications can run within an Agilicus hosting platform, or elsewhere on the internet. The possible values have the following meanings:   - `hosted`: the application runs on the Agilicus hosting platform.   - `external`: the application runs elsewhere on the internet. External applications     will not create instances in the Agilicus hosting platform. However, they will     be able to use Agilicus for Identity and Authentication. . [optional]  # noqa: E501
            service_account_id (str): Service account user GUID used to deploy the application. [optional]  # noqa: E501
            service_account_required (bool): If service_account_enabled field is set to true, a service account will be created. If service_account_enabled field is set to false, the service account will be deleted. If the service_account_enabled field is not set no action on the service account is taken. . [optional]  # noqa: E501
            application_type (str): The type of application meanings:   - `user_defined`: A user defined application.   - `internal`: An internal application used by agilicus services. . [optional] if omitted the server will use the default value of "user_defined"  # noqa: E501
            name_slug (K8sSlug): [optional]  # noqa: E501
            workload_config (WorkloadConfiguration): [optional]  # noqa: E501
            admin_state (ApplicationStateSelector): [optional]  # noqa: E501
            alternate_mode_setting (AlternateModeSetting): [optional]  # noqa: E501
            launchers ([str]): A list of launchers that can be used to launch this application. . [optional]  # noqa: E501
        """

        _check_type = kwargs.pop('_check_type', True)
        _spec_property_naming = kwargs.pop('_spec_property_naming', False)
        _path_to_item = kwargs.pop('_path_to_item', ())
        _configuration = kwargs.pop('_configuration', None)
        _visited_composed_classes = kwargs.pop('_visited_composed_classes', ())

        self = super(OpenApiModel, cls).__new__(cls)

        if args:
            raise ApiTypeError(
                "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
                    args,
                    self.__class__.__name__,
                ),
                path_to_item=_path_to_item,
                valid_classes=(self.__class__,),
            )

        self._data_store = {}
        self._check_type = _check_type
        self._spec_property_naming = _spec_property_naming
        self._path_to_item = _path_to_item
        self._configuration = _configuration
        self._visited_composed_classes = _visited_composed_classes + (self.__class__,)

        self.name = name
        self.category = category
        self.org_id = org_id
        for var_name, var_value in kwargs.items():
            if var_name not in self.attribute_map and \
                        self._configuration is not None and \
                        self._configuration.discard_unknown_keys and \
                        self.additional_properties_type is None:
                # discard variable.
                continue
            setattr(self, var_name, var_value)
        return self

    def __python_set(val):
        return set(val)
 
    required_properties = __python_set([
        '_data_store',
        '_check_type',
        '_spec_property_naming',
        '_path_to_item',
        '_configuration',
        '_visited_composed_classes',
    ])

    @convert_js_args_to_python_args
    def __init__(self, name, category, org_id, *args, **kwargs):  # noqa: E501
        """Application - a model defined in OpenAPI

        Args:
            name (str): application name
            category (str): application category
            org_id (str): organisation id

        Keyword Args:
            _check_type (bool): if True, values for parameters in openapi_types
                                will be type checked and a TypeError will be
                                raised if the wrong type is input.
                                Defaults to True
            _path_to_item (tuple/list): This is a list of keys or values to
                                drill down to the model in received_data
                                when deserializing a response
            _spec_property_naming (bool): True if the variable names in the input data
                                are serialized names, as specified in the OpenAPI document.
                                False if the variable names in the input data
                                are pythonic names, e.g. snake case (default)
            _configuration (Configuration): the instance to use when
                                deserializing a file_type parameter.
                                If passed, type conversion is attempted
                                If omitted no type conversion is done.
            _visited_composed_classes (tuple): This stores a tuple of
                                classes that we have traveled through so that
                                if we see that class again we will not use its
                                discriminator again.
                                When traveling through a discriminator, the
                                composed schema that is
                                is traveled through is added to this set.
                                For example if Animal has a discriminator
                                petType and we pass in "Dog", and the class Dog
                                allOf includes Animal, we move through Animal
                                once using the discriminator, and pick Dog.
                                Then in Dog, we will make an instance of the
                                Animal class but this time we won't travel
                                through its discriminator because we passed in
                                _visited_composed_classes = (Animal,)
            created (datetime): Creation time. [optional]  # noqa: E501
            id (str): application service id. [optional]  # noqa: E501
            parent_id (str): For inheritance, defines the parent id.. [optional]  # noqa: E501
            description (str): Application description text. [optional]  # noqa: E501
            image (str): image registry path and name. [optional]  # noqa: E501
            image_username (str): registry username. [optional]  # noqa: E501
            image_password (str): registry password. [optional]  # noqa: E501
            image_credentials_type (str): type of credentials for image. [optional]  # noqa: E501
            environments ([Environment]): List of environments. [optional]  # noqa: E501
            contact_email (str): Administrator contact email. [optional]  # noqa: E501
            monitoring_config (ApplicationMonitoringConfig): [optional]  # noqa: E501
            port (int): The transport layer port the application listens on for requests. E.g. if the application listens for HTTP requests on the standard port, port 80, set this to 80. . [optional]  # noqa: E501
            healthcheck_uri (str): health check URI. [optional]  # noqa: E501
            roles (RoleList): [optional]  # noqa: E501
            roles_config (RolesConfig): [optional]  # noqa: E501
            rules_config (RulesConfig): [optional]  # noqa: E501
            definitions ([Definition]): List of definitions. [optional]  # noqa: E501
            assignments ([ApplicationAssignment]): Controls the Organisations which have access to Environments of this Application. . [optional]  # noqa: E501
            owned (bool): Whether this Application is owned by the provided organisation. . [optional]  # noqa: E501
            maintained (bool): Whether this Application has an Environment maintained by the provided organisation. . [optional]  # noqa: E501
            assigned (bool): Whether an Environment is assigned to this Application. . [optional]  # noqa: E501
            published (str): Whether or not this Application is published, and if so, how. An application that has been published somewhere will have high level details about it visible (through apis intended to expose published applications), such as its name and description. The enum values mean the following:  - no: This application is not published. It will only be visibile to users with       permission to access the application, or to administrators.  - public: This application is published to the public catalogue. Any user who       can request access to the organisation will see high level details about this       application. . [optional] if omitted the server will use the default value of "no"  # noqa: E501
            default_role_id (str, none_type): The id of the default role to use for this application. This role will be assigned to users granted access to this application by default, unless overridden. This value must point to a valid Role for this application. A string of length 0 will clear out the default role.. [optional]  # noqa: E501
            default_role_name (str, none_type): The name of the default role. Does not change which role is used. Provided for convenience. . [optional]  # noqa: E501
            icon_url (str): A url pointing to an icon representing this application. . [optional]  # noqa: E501
            display_info (DisplayInfo): [optional]  # noqa: E501
            updated (datetime): Update time. [optional]  # noqa: E501
            location (str): Where the application runs. Applications can run within an Agilicus hosting platform, or elsewhere on the internet. The possible values have the following meanings:   - `hosted`: the application runs on the Agilicus hosting platform.   - `external`: the application runs elsewhere on the internet. External applications     will not create instances in the Agilicus hosting platform. However, they will     be able to use Agilicus for Identity and Authentication. . [optional]  # noqa: E501
            service_account_id (str): Service account user GUID used to deploy the application. [optional]  # noqa: E501
            service_account_required (bool): If service_account_enabled field is set to true, a service account will be created. If service_account_enabled field is set to false, the service account will be deleted. If the service_account_enabled field is not set no action on the service account is taken. . [optional]  # noqa: E501
            application_type (str): The type of application meanings:   - `user_defined`: A user defined application.   - `internal`: An internal application used by agilicus services. . [optional] if omitted the server will use the default value of "user_defined"  # noqa: E501
            name_slug (K8sSlug): [optional]  # noqa: E501
            workload_config (WorkloadConfiguration): [optional]  # noqa: E501
            admin_state (ApplicationStateSelector): [optional]  # noqa: E501
            alternate_mode_setting (AlternateModeSetting): [optional]  # noqa: E501
            launchers ([str]): A list of launchers that can be used to launch this application. . [optional]  # noqa: E501
        """

        _check_type = kwargs.pop('_check_type', True)
        _spec_property_naming = kwargs.pop('_spec_property_naming', False)
        _path_to_item = kwargs.pop('_path_to_item', ())
        _configuration = kwargs.pop('_configuration', None)
        _visited_composed_classes = kwargs.pop('_visited_composed_classes', ())

        if args:
            raise ApiTypeError(
                "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
                    args,
                    self.__class__.__name__,
                ),
                path_to_item=_path_to_item,
                valid_classes=(self.__class__,),
            )

        self._data_store = {}
        self._check_type = _check_type
        self._spec_property_naming = _spec_property_naming
        self._path_to_item = _path_to_item
        self._configuration = _configuration
        self._visited_composed_classes = _visited_composed_classes + (self.__class__,)

        self.name = name
        self.category = category
        self.org_id = org_id
        for var_name, var_value in kwargs.items():
            if var_name not in self.attribute_map and \
                        self._configuration is not None and \
                        self._configuration.discard_unknown_keys and \
                        self.additional_properties_type is None:
                # discard variable.
                continue
            setattr(self, var_name, var_value)
            if var_name in self.read_only_vars:
                raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate "
                                     f"class with read only attributes.")

