# Path: marathon/models/base.py
# class MarathonObject:
#     """Base Marathon object."""
# 
#     def __repr__(self):
#         return "{clazz}::{obj}".format(clazz=self.__class__.__name__, obj=self.to_json(minimal=False))
# 
#     def __eq__(self, other):
#         try:
#             return self.__dict__ == other.__dict__
#         except Exception:
#             return False
# 
#     def __hash__(self):
#         # Technically this class shouldn't be hashable because it often
#         # contains mutable fields, but in practice this class is used more
#         # like a record or namedtuple.
#         return hash(self.to_json())
# 
#     def json_repr(self, minimal=False):
#         """Construct a JSON-friendly representation of the object.
# 
#         :param bool minimal: Construct a minimal representation of the object (ignore nulls and empty collections)
# 
#         :rtype: dict
#         """
#         if minimal:
#             return {to_camel_case(k): v for k, v in vars(self).items() if (v or v is False or v == 0)}
#         else:
#             return {to_camel_case(k): v for k, v in vars(self).items()}
# 
#     @classmethod
#     def from_json(cls, attributes):
#         """Construct an object from a parsed response.
# 
#         :param dict attributes: object attributes from parsed response
#         """
#         return cls(**{to_snake_case(k): v for k, v in attributes.items()})
# 
#     def to_json(self, minimal=True):
#         """Encode an object as a JSON string.
# 
#         :param bool minimal: Construct a minimal representation of the object (ignore nulls and empty collections)
# 
#         :rtype: str
#         """
#         if minimal:
#             return json.dumps(self.json_repr(minimal=True), cls=MarathonMinimalJsonEncoder, sort_keys=True)
#         else:
#             return json.dumps(self.json_repr(), cls=MarathonJsonEncoder, sort_keys=True)
# 
# class MarathonResource(MarathonObject):
# 
#     """Base Marathon resource."""
# 
#     def __repr__(self):
#         if 'id' in list(vars(self).keys()):
#             return f"{self.__class__.__name__}::{self.id}"
#         else:
#             return "{clazz}::{obj}".format(clazz=self.__class__.__name__, obj=self.to_json())
# 
#     def __eq__(self, other):
#         try:
#             return self.__dict__ == other.__dict__
#         except Exception:
#             return False
# 
#     def __hash__(self):
#         # Technically this class shouldn't be hashable because it often
#         # contains mutable fields, but in practice this class is used more
#         # like a record or namedtuple.
#         return hash(self.to_json())
# 
#     def __str__(self):
#         return f"{self.__class__.__name__}::" + str(self.__dict__)
# 
# def assert_valid_path(path):
#     """Checks if a path is a correct format that Marathon expects. Raises ValueError if not valid.
# 
#     :param str path: The app id.
# 
#     :rtype: str
#     """
#     if path is None:
#         return
#     # As seen in:
#     # https://github.com/mesosphere/marathon/blob/0c11661ca2f259f8a903d114ef79023649a6f04b/src/main/scala/mesosphere/marathon/state/PathId.scala#L71
#     for id in filter(None, path.strip('/').split('/')):
#         if not ID_PATTERN.match(id):
#             raise ValueError(
#                 'invalid path (allowed: lowercase letters, digits, hyphen, "/", ".", ".."): %r' % path)
#     return path


from .base import MarathonObject, MarathonResource, assert_valid_path
    """Marathon Application resource.

    See: https://mesosphere.github.io/marathon/docs/rest-api.html#deployments

    :param str action: action
    :param str app: app id
    :param str apps: app id (see https://github.com/mesosphere/marathon/pull/802)
    :param type readiness_check_results: Undocumented
    """

    def __init__(self, action=None, app=None, apps=None, type=None, readiness_check_results=None, pod=None):
        self.action = action
        self.app = assert_valid_path(app)
        self.apps = assert_valid_path(apps)
        self.pod = pod
        self.type = type  # TODO: Remove builtin shadow
        self.readiness_check_results = readiness_check_results  # TODO: The docs say this is called just "readinessChecks?"


class MarathonDeploymentPlan(MarathonObject):

    def __init__(self, original=None, target=None,
                 steps=None, id=None, version=None):
        self.original = MarathonDeploymentOriginalState.from_json(original)
        self.target = MarathonDeploymentTargetState.from_json(target)
        self.steps = [MarathonDeploymentStep.from_json(x) for x in steps]
        self.id = id
        self.version = version



# Path: marathon/models/base.py
# class MarathonObject:
#     """Base Marathon object."""
# 
#     def __repr__(self):
#         return "{clazz}::{obj}".format(clazz=self.__class__.__name__, obj=self.to_json(minimal=False))
# 
#     def __eq__(self, other):
#         try:
#             return self.__dict__ == other.__dict__
#         except Exception:
#             return False
# 
#     def __hash__(self):
#         # Technically this class shouldn't be hashable because it often
#         # contains mutable fields, but in practice this class is used more
#         # like a record or namedtuple.
#         return hash(self.to_json())
# 
#     def json_repr(self, minimal=False):
#         """Construct a JSON-friendly representation of the object.
# 
#         :param bool minimal: Construct a minimal representation of the object (ignore nulls and empty collections)
# 
#         :rtype: dict
#         """
#         if minimal:
#             return {to_camel_case(k): v for k, v in vars(self).items() if (v or v is False or v == 0)}
#         else:
#             return {to_camel_case(k): v for k, v in vars(self).items()}
# 
#     @classmethod
#     def from_json(cls, attributes):
#         """Construct an object from a parsed response.
# 
#         :param dict attributes: object attributes from parsed response
#         """
#         return cls(**{to_snake_case(k): v for k, v in attributes.items()})
# 
#     def to_json(self, minimal=True):
#         """Encode an object as a JSON string.
# 
#         :param bool minimal: Construct a minimal representation of the object (ignore nulls and empty collections)
# 
#         :rtype: str
#         """
#         if minimal:
#             return json.dumps(self.json_repr(minimal=True), cls=MarathonMinimalJsonEncoder, sort_keys=True)
#         else:
#             return json.dumps(self.json_repr(), cls=MarathonJsonEncoder, sort_keys=True)
# 
# class MarathonResource(MarathonObject):
# 
#     """Base Marathon resource."""
# 
#     def __repr__(self):
#         if 'id' in list(vars(self).keys()):
#             return f"{self.__class__.__name__}::{self.id}"
#         else:
#             return "{clazz}::{obj}".format(clazz=self.__class__.__name__, obj=self.to_json())
# 
#     def __eq__(self, other):
#         try:
#             return self.__dict__ == other.__dict__
#         except Exception:
#             return False
# 
#     def __hash__(self):
#         # Technically this class shouldn't be hashable because it often
#         # contains mutable fields, but in practice this class is used more
#         # like a record or namedtuple.
#         return hash(self.to_json())
# 
#     def __str__(self):
#         return f"{self.__class__.__name__}::" + str(self.__dict__)
# 
# def assert_valid_path(path):
#     """Checks if a path is a correct format that Marathon expects. Raises ValueError if not valid.
# 
#     :param str path: The app id.
# 
#     :rtype: str
#     """
#     if path is None:
#         return
#     # As seen in:
#     # https://github.com/mesosphere/marathon/blob/0c11661ca2f259f8a903d114ef79023649a6f04b/src/main/scala/mesosphere/marathon/state/PathId.scala#L71
#     for id in filter(None, path.strip('/').split('/')):
#         if not ID_PATTERN.match(id):
#             raise ValueError(
#                 'invalid path (allowed: lowercase letters, digits, hyphen, "/", ".", ".."): %r' % path)
#     return path


# Path: marathon/models/deployment.py
from .base import MarathonObject, MarathonResource, assert_valid_path

    """Marathon Application resource.

    See: https://mesosphere.github.io/marathon/docs/rest-api.html#deployments

    :param str action: action
    :param str app: app id
    :param str apps: app id (see https://github.com/mesosphere/marathon/pull/802)
    :param type readiness_check_results: Undocumented
    """

    def __init__(self, action=None, app=None, apps=None, type=None, readiness_check_results=None, pod=None):
        self.action = action
        self.app = assert_valid_path(app)
        self.apps = assert_valid_path(apps)
        self.pod = pod
        self.type = type  # TODO: Remove builtin shadow
        self.readiness_check_results = readiness_check_results  # TODO: The docs say this is called just "readinessChecks?"


class MarathonDeploymentPlan(MarathonObject):

    def __init__(self, original=None, target=None,
                 steps=None, id=None, version=None):
        self.original = MarathonDeploymentOriginalState.from_json(original)
        self.target = MarathonDeploymentTargetState.from_json(target)
        self.steps = [MarathonDeploymentStep.from_json(x) for x in steps]
        self.id = id
        self.version = version



class MarathonDeploymentStep(MarathonObject):