# coding: utf-8

"""
    The Jira Cloud platform REST API

    Jira Cloud platform REST API documentation

    The version of the OpenAPI document: 1001.0.0-SNAPSHOT-7ce0ee67a52d004425175cea962ad1c1c7200181
    Contact: ecosystem@atlassian.com
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from datetime import date
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from jira_client.models.simple_link import SimpleLink
from jira_client.models.version_approver import VersionApprover
from jira_client.models.version_issues_status import VersionIssuesStatus
from typing import Optional, Set
from typing_extensions import Self

class Version(BaseModel):
    """
    Details about a project version.
    """ # noqa: E501
    approvers: Optional[List[VersionApprover]] = Field(default=None, description="If the expand option `approvers` is used, returns a list containing the approvers for this version.")
    archived: Optional[StrictBool] = Field(default=None, description="Indicates that the version is archived. Optional when creating or updating a version.")
    description: Optional[StrictStr] = Field(default=None, description="The description of the version. Optional when creating or updating a version. The maximum size is 16,384 bytes.")
    driver: Optional[StrictStr] = Field(default=None, description="If the expand option `driver` is used, returns the Atlassian account ID of the driver.")
    expand: Optional[StrictStr] = Field(default=None, description="Use [expand](em>#expansion) to include additional information about version in the response. This parameter accepts a comma-separated list. Expand options include:   *  `operations` Returns the list of operations available for this version.  *  `issuesstatus` Returns the count of issues in this version for each of the status categories *to do*, *in progress*, *done*, and *unmapped*. The *unmapped* property contains a count of issues with a status other than *to do*, *in progress*, and *done*.  *  `driver` Returns the Atlassian account ID of the version driver.  *  `approvers` Returns a list containing approvers for this version.  Optional for create and update.")
    id: Optional[StrictStr] = Field(default=None, description="The ID of the version.")
    issues_status_for_fix_version: Optional[VersionIssuesStatus] = Field(default=None, description="If the expand option `issuesstatus` is used, returns the count of issues in this version for each of the status categories *to do*, *in progress*, *done*, and *unmapped*. The *unmapped* property contains a count of issues with a status other than *to do*, *in progress*, and *done*.", alias="issuesStatusForFixVersion")
    move_unfixed_issues_to: Optional[StrictStr] = Field(default=None, description="The URL of the self link to the version to which all unfixed issues are moved when a version is released. Not applicable when creating a version. Optional when updating a version.", alias="moveUnfixedIssuesTo")
    name: Optional[StrictStr] = Field(default=None, description="The unique name of the version. Required when creating a version. Optional when updating a version. The maximum length is 255 characters.")
    operations: Optional[List[SimpleLink]] = Field(default=None, description="If the expand option `operations` is used, returns the list of operations available for this version.")
    overdue: Optional[StrictBool] = Field(default=None, description="Indicates that the version is overdue.")
    project: Optional[StrictStr] = Field(default=None, description="Deprecated. Use `projectId`.")
    project_id: Optional[StrictInt] = Field(default=None, description="The ID of the project to which this version is attached. Required when creating a version. Not applicable when updating a version.", alias="projectId")
    release_date: Optional[date] = Field(default=None, description="The release date of the version. Expressed in ISO 8601 format (yyyy-mm-dd). Optional when creating or updating a version.", alias="releaseDate")
    released: Optional[StrictBool] = Field(default=None, description="Indicates that the version is released. If the version is released a request to release again is ignored. Not applicable when creating a version. Optional when updating a version.")
    var_self: Optional[StrictStr] = Field(default=None, description="The URL of the version.", alias="self")
    start_date: Optional[date] = Field(default=None, description="The start date of the version. Expressed in ISO 8601 format (yyyy-mm-dd). Optional when creating or updating a version.", alias="startDate")
    user_release_date: Optional[StrictStr] = Field(default=None, description="The date on which work on this version is expected to finish, expressed in the instance's *Day/Month/Year Format* date format.", alias="userReleaseDate")
    user_start_date: Optional[StrictStr] = Field(default=None, description="The date on which work on this version is expected to start, expressed in the instance's *Day/Month/Year Format* date format.", alias="userStartDate")
    __properties: ClassVar[List[str]] = ["approvers", "archived", "description", "driver", "expand", "id", "issuesStatusForFixVersion", "moveUnfixedIssuesTo", "name", "operations", "overdue", "project", "projectId", "releaseDate", "released", "self", "startDate", "userReleaseDate", "userStartDate"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of Version from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        * OpenAPI `readOnly` fields are excluded.
        """
        excluded_fields: Set[str] = set([
            "approvers",
            "driver",
            "id",
            "issues_status_for_fix_version",
            "operations",
            "overdue",
            "var_self",
            "user_release_date",
            "user_start_date",
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of each item in approvers (list)
        _items = []
        if self.approvers:
            for _item_approvers in self.approvers:
                if _item_approvers:
                    _items.append(_item_approvers.to_dict())
            _dict['approvers'] = _items
        # override the default output from pydantic by calling `to_dict()` of issues_status_for_fix_version
        if self.issues_status_for_fix_version:
            _dict['issuesStatusForFixVersion'] = self.issues_status_for_fix_version.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in operations (list)
        _items = []
        if self.operations:
            for _item_operations in self.operations:
                if _item_operations:
                    _items.append(_item_operations.to_dict())
            _dict['operations'] = _items
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of Version from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "approvers": [VersionApprover.from_dict(_item) for _item in obj["approvers"]] if obj.get("approvers") is not None else None,
            "archived": obj.get("archived"),
            "description": obj.get("description"),
            "driver": obj.get("driver"),
            "expand": obj.get("expand"),
            "id": obj.get("id"),
            "issuesStatusForFixVersion": VersionIssuesStatus.from_dict(obj["issuesStatusForFixVersion"]) if obj.get("issuesStatusForFixVersion") is not None else None,
            "moveUnfixedIssuesTo": obj.get("moveUnfixedIssuesTo"),
            "name": obj.get("name"),
            "operations": [SimpleLink.from_dict(_item) for _item in obj["operations"]] if obj.get("operations") is not None else None,
            "overdue": obj.get("overdue"),
            "project": obj.get("project"),
            "projectId": obj.get("projectId"),
            "releaseDate": obj.get("releaseDate"),
            "released": obj.get("released"),
            "self": obj.get("self"),
            "startDate": obj.get("startDate"),
            "userReleaseDate": obj.get("userReleaseDate"),
            "userStartDate": obj.get("userStartDate")
        })
        return _obj


