# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# coding: utf-8

"""
    Submarine API

    The Submarine REST API allows you to access Submarine resources such as,  experiments, environments and notebooks. The  API is hosted under the /v1 path on the Submarine server. For example,  to list experiments on a server hosted at http://localhost:8080, access http://localhost:8080/api/v1/experiment/  # noqa: E501

    The version of the OpenAPI document: 0.8.0
    Contact: dev@submarine.apache.org
    Generated by: https://openapi-generator.tech
"""


import pprint
import re  # noqa: F401

import six

from submarine.client.configuration import Configuration


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

    Do not edit the class manually.
    """

    """
    Attributes:
      openapi_types (dict): The key is attribute name
                            and the value is attribute type.
      attribute_map (dict): The key is attribute name
                            and the value is json key in definition.
    """
    openapi_types = {'environment': 'EnvironmentSpec', 'meta': 'NotebookMeta', 'spec': 'NotebookPodSpec'}

    attribute_map = {'environment': 'environment', 'meta': 'meta', 'spec': 'spec'}

    def __init__(self, environment=None, meta=None, spec=None, local_vars_configuration=None):  # noqa: E501
        """NotebookSpec - a model defined in OpenAPI"""  # noqa: E501
        if local_vars_configuration is None:
            local_vars_configuration = Configuration()
        self.local_vars_configuration = local_vars_configuration

        self._environment = None
        self._meta = None
        self._spec = None
        self.discriminator = None

        if environment is not None:
            self.environment = environment
        if meta is not None:
            self.meta = meta
        if spec is not None:
            self.spec = spec

    @property
    def environment(self):
        """Gets the environment of this NotebookSpec.  # noqa: E501


        :return: The environment of this NotebookSpec.  # noqa: E501
        :rtype: EnvironmentSpec
        """
        return self._environment

    @environment.setter
    def environment(self, environment):
        """Sets the environment of this NotebookSpec.


        :param environment: The environment of this NotebookSpec.  # noqa: E501
        :type: EnvironmentSpec
        """

        self._environment = environment

    @property
    def meta(self):
        """Gets the meta of this NotebookSpec.  # noqa: E501


        :return: The meta of this NotebookSpec.  # noqa: E501
        :rtype: NotebookMeta
        """
        return self._meta

    @meta.setter
    def meta(self, meta):
        """Sets the meta of this NotebookSpec.


        :param meta: The meta of this NotebookSpec.  # noqa: E501
        :type: NotebookMeta
        """

        self._meta = meta

    @property
    def spec(self):
        """Gets the spec of this NotebookSpec.  # noqa: E501


        :return: The spec of this NotebookSpec.  # noqa: E501
        :rtype: NotebookPodSpec
        """
        return self._spec

    @spec.setter
    def spec(self, spec):
        """Sets the spec of this NotebookSpec.


        :param spec: The spec of this NotebookSpec.  # noqa: E501
        :type: NotebookPodSpec
        """

        self._spec = spec

    def to_dict(self):
        """Returns the model properties as a dict"""
        result = {}

        for attr, _ in six.iteritems(self.openapi_types):
            value = getattr(self, attr)
            if isinstance(value, list):
                result[attr] = list(map(lambda x: x.to_dict() if hasattr(x, "to_dict") else x, value))
            elif hasattr(value, "to_dict"):
                result[attr] = value.to_dict()
            elif isinstance(value, dict):
                result[attr] = dict(
                    map(
                        lambda item: (item[0], item[1].to_dict()) if hasattr(item[1], "to_dict") else item,
                        value.items(),
                    )
                )
            else:
                result[attr] = value

        return result

    def to_str(self):
        """Returns the string representation of the model"""
        return pprint.pformat(self.to_dict())

    def __repr__(self):
        """For `print` and `pprint`"""
        return self.to_str()

    def __eq__(self, other):
        """Returns true if both objects are equal"""
        if not isinstance(other, NotebookSpec):
            return False

        return self.to_dict() == other.to_dict()

    def __ne__(self, other):
        """Returns true if both objects are not equal"""
        if not isinstance(other, NotebookSpec):
            return True

        return self.to_dict() != other.to_dict()
