# 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 GitCodeSpec(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 = {
        'branch': 'str',
        'password': 'str',
        'trust_certs': 'bool',
        'url': 'str',
        'username': 'str',
    }

    attribute_map = {
        'branch': 'branch',
        'password': 'password',
        'trust_certs': 'trustCerts',
        'url': 'url',
        'username': 'username',
    }

    def __init__(
        self,
        branch=None,
        password=None,
        trust_certs=None,
        url=None,
        username=None,
        local_vars_configuration=None,
    ):  # noqa: E501
        """GitCodeSpec - 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._branch = None
        self._password = None
        self._trust_certs = None
        self._url = None
        self._username = None
        self.discriminator = None

        if branch is not None:
            self.branch = branch
        if password is not None:
            self.password = password
        if trust_certs is not None:
            self.trust_certs = trust_certs
        if url is not None:
            self.url = url
        if username is not None:
            self.username = username

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


        :return: The branch of this GitCodeSpec.  # noqa: E501
        :rtype: str
        """
        return self._branch

    @branch.setter
    def branch(self, branch):
        """Sets the branch of this GitCodeSpec.


        :param branch: The branch of this GitCodeSpec.  # noqa: E501
        :type: str
        """

        self._branch = branch

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


        :return: The password of this GitCodeSpec.  # noqa: E501
        :rtype: str
        """
        return self._password

    @password.setter
    def password(self, password):
        """Sets the password of this GitCodeSpec.


        :param password: The password of this GitCodeSpec.  # noqa: E501
        :type: str
        """

        self._password = password

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


        :return: The trust_certs of this GitCodeSpec.  # noqa: E501
        :rtype: bool
        """
        return self._trust_certs

    @trust_certs.setter
    def trust_certs(self, trust_certs):
        """Sets the trust_certs of this GitCodeSpec.


        :param trust_certs: The trust_certs of this GitCodeSpec.  # noqa: E501
        :type: bool
        """

        self._trust_certs = trust_certs

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


        :return: The url of this GitCodeSpec.  # noqa: E501
        :rtype: str
        """
        return self._url

    @url.setter
    def url(self, url):
        """Sets the url of this GitCodeSpec.


        :param url: The url of this GitCodeSpec.  # noqa: E501
        :type: str
        """

        self._url = url

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


        :return: The username of this GitCodeSpec.  # noqa: E501
        :rtype: str
        """
        return self._username

    @username.setter
    def username(self, username):
        """Sets the username of this GitCodeSpec.


        :param username: The username of this GitCodeSpec.  # noqa: E501
        :type: str
        """

        self._username = username

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

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