# 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 pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional
from jira_client.models.user import User
from typing import Optional, Set
from typing_extensions import Self

class ComponentWithIssueCount(BaseModel):
    """
    Details about a component with a count of the issues it contains.
    """ # noqa: E501
    assignee: Optional[User] = Field(default=None, description="The details of the user associated with `assigneeType`, if any. See `realAssignee` for details of the user assigned to issues created with this component.")
    assignee_type: Optional[StrictStr] = Field(default=None, description="The nominal user type used to determine the assignee for issues created with this component. See `realAssigneeType` for details on how the type of the user, and hence the user, assigned to issues is determined. Takes the following values:   *  `PROJECT_LEAD` the assignee to any issues created with this component is nominally the lead for the project the component is in.  *  `COMPONENT_LEAD` the assignee to any issues created with this component is nominally the lead for the component.  *  `UNASSIGNED` an assignee is not set for issues created with this component.  *  `PROJECT_DEFAULT` the assignee to any issues created with this component is nominally the default assignee for the project that the component is in.", alias="assigneeType")
    description: Optional[StrictStr] = Field(default=None, description="The description for the component.")
    id: Optional[StrictStr] = Field(default=None, description="The unique identifier for the component.")
    is_assignee_type_valid: Optional[StrictBool] = Field(default=None, description="Whether a user is associated with `assigneeType`. For example, if the `assigneeType` is set to `COMPONENT_LEAD` but the component lead is not set, then `false` is returned.", alias="isAssigneeTypeValid")
    issue_count: Optional[StrictInt] = Field(default=None, description="Count of issues for the component.", alias="issueCount")
    lead: Optional[User] = Field(default=None, description="The user details for the component's lead user.")
    name: Optional[StrictStr] = Field(default=None, description="The name for the component.")
    project: Optional[StrictStr] = Field(default=None, description="The key of the project to which the component is assigned.")
    project_id: Optional[StrictInt] = Field(default=None, description="Not used.", alias="projectId")
    real_assignee: Optional[User] = Field(default=None, description="The user assigned to issues created with this component, when `assigneeType` does not identify a valid assignee.", alias="realAssignee")
    real_assignee_type: Optional[StrictStr] = Field(default=None, description="The type of the assignee that is assigned to issues created with this component, when an assignee cannot be set from the `assigneeType`. For example, `assigneeType` is set to `COMPONENT_LEAD` but no component lead is set. This property is set to one of the following values:   *  `PROJECT_LEAD` when `assigneeType` is `PROJECT_LEAD` and the project lead has permission to be assigned issues in the project that the component is in.  *  `COMPONENT_LEAD` when `assignee`Type is `COMPONENT_LEAD` and the component lead has permission to be assigned issues in the project that the component is in.  *  `UNASSIGNED` when `assigneeType` is `UNASSIGNED` and Jira is configured to allow unassigned issues.  *  `PROJECT_DEFAULT` when none of the preceding cases are true.", alias="realAssigneeType")
    var_self: Optional[StrictStr] = Field(default=None, description="The URL for this count of the issues contained in the component.", alias="self")
    __properties: ClassVar[List[str]] = ["assignee", "assigneeType", "description", "id", "isAssigneeTypeValid", "issueCount", "lead", "name", "project", "projectId", "realAssignee", "realAssigneeType", "self"]

    @field_validator('assignee_type')
    def assignee_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['PROJECT_DEFAULT', 'COMPONENT_LEAD', 'PROJECT_LEAD', 'UNASSIGNED']):
            raise ValueError("must be one of enum values ('PROJECT_DEFAULT', 'COMPONENT_LEAD', 'PROJECT_LEAD', 'UNASSIGNED')")
        return value

    @field_validator('real_assignee_type')
    def real_assignee_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['PROJECT_DEFAULT', 'COMPONENT_LEAD', 'PROJECT_LEAD', 'UNASSIGNED']):
            raise ValueError("must be one of enum values ('PROJECT_DEFAULT', 'COMPONENT_LEAD', 'PROJECT_LEAD', 'UNASSIGNED')")
        return value

    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 ComponentWithIssueCount 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.
        * OpenAPI `readOnly` fields are excluded.
        """
        excluded_fields: Set[str] = set([
            "assignee_type",
            "description",
            "id",
            "is_assignee_type_valid",
            "issue_count",
            "name",
            "project",
            "project_id",
            "real_assignee_type",
            "var_self",
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of assignee
        if self.assignee:
            _dict['assignee'] = self.assignee.to_dict()
        # override the default output from pydantic by calling `to_dict()` of lead
        if self.lead:
            _dict['lead'] = self.lead.to_dict()
        # override the default output from pydantic by calling `to_dict()` of real_assignee
        if self.real_assignee:
            _dict['realAssignee'] = self.real_assignee.to_dict()
        return _dict

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

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

        _obj = cls.model_validate({
            "assignee": User.from_dict(obj["assignee"]) if obj.get("assignee") is not None else None,
            "assigneeType": obj.get("assigneeType"),
            "description": obj.get("description"),
            "id": obj.get("id"),
            "isAssigneeTypeValid": obj.get("isAssigneeTypeValid"),
            "issueCount": obj.get("issueCount"),
            "lead": User.from_dict(obj["lead"]) if obj.get("lead") is not None else None,
            "name": obj.get("name"),
            "project": obj.get("project"),
            "projectId": obj.get("projectId"),
            "realAssignee": User.from_dict(obj["realAssignee"]) if obj.get("realAssignee") is not None else None,
            "realAssigneeType": obj.get("realAssigneeType"),
            "self": obj.get("self")
        })
        return _obj


