# 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-RC0
    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 KernelSpec(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 = {
        'channels': 'list[str]',
        'conda_dependencies': 'list[str]',
        'name': 'str',
        'pip_dependencies': 'list[str]',
    }

    attribute_map = {
        'channels': 'channels',
        'conda_dependencies': 'condaDependencies',
        'name': 'name',
        'pip_dependencies': 'pipDependencies',
    }

    def __init__(
        self,
        channels=None,
        conda_dependencies=None,
        name=None,
        pip_dependencies=None,
        local_vars_configuration=None,
    ):  # noqa: E501
        """KernelSpec - 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._channels = None
        self._conda_dependencies = None
        self._name = None
        self._pip_dependencies = None
        self.discriminator = None

        if channels is not None:
            self.channels = channels
        if conda_dependencies is not None:
            self.conda_dependencies = conda_dependencies
        if name is not None:
            self.name = name
        if pip_dependencies is not None:
            self.pip_dependencies = pip_dependencies

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


        :return: The channels of this KernelSpec.  # noqa: E501
        :rtype: list[str]
        """
        return self._channels

    @channels.setter
    def channels(self, channels):
        """Sets the channels of this KernelSpec.


        :param channels: The channels of this KernelSpec.  # noqa: E501
        :type: list[str]
        """

        self._channels = channels

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


        :return: The conda_dependencies of this KernelSpec.  # noqa: E501
        :rtype: list[str]
        """
        return self._conda_dependencies

    @conda_dependencies.setter
    def conda_dependencies(self, conda_dependencies):
        """Sets the conda_dependencies of this KernelSpec.


        :param conda_dependencies: The conda_dependencies of this KernelSpec.  # noqa: E501
        :type: list[str]
        """

        self._conda_dependencies = conda_dependencies

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


        :return: The name of this KernelSpec.  # noqa: E501
        :rtype: str
        """
        return self._name

    @name.setter
    def name(self, name):
        """Sets the name of this KernelSpec.


        :param name: The name of this KernelSpec.  # noqa: E501
        :type: str
        """

        self._name = name

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


        :return: The pip_dependencies of this KernelSpec.  # noqa: E501
        :rtype: list[str]
        """
        return self._pip_dependencies

    @pip_dependencies.setter
    def pip_dependencies(self, pip_dependencies):
        """Sets the pip_dependencies of this KernelSpec.


        :param pip_dependencies: The pip_dependencies of this KernelSpec.  # noqa: E501
        :type: list[str]
        """

        self._pip_dependencies = pip_dependencies

    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, KernelSpec):
            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, KernelSpec):
            return True

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