# 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, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from jira_client.models.target_classification import TargetClassification
from jira_client.models.target_mandatory_fields import TargetMandatoryFields
from jira_client.models.target_status import TargetStatus
from typing import Optional, Set
from typing_extensions import Self

class TargetToSourcesMapping(BaseModel):
    """
    An object representing the mapping of issues and data related to destination entities, like fields and statuses, that are required during a bulk move.
    """ # noqa: E501
    infer_classification_defaults: StrictBool = Field(description="If `true`, when issues are moved into this target group, they will adopt the target project's default classification, if they don't have a classification already. If they do have a classification, it will be kept the same even after the move. Leave `targetClassification` empty when using this.  If `false`, you must provide a `targetClassification` mapping for each classification associated with the selected issues.  [Benefit from data classification](https://support.atlassian.com/security-and-access-policies/docs/what-is-data-classification/)", alias="inferClassificationDefaults")
    infer_field_defaults: StrictBool = Field(description="If `true`, values from the source issues will be retained for the mandatory fields in the field configuration of the destination project. The `targetMandatoryFields` property shouldn't be defined.  If `false`, the user is required to set values for mandatory fields present in the field configuration of the destination project. Provide input by defining the `targetMandatoryFields` property", alias="inferFieldDefaults")
    infer_status_defaults: StrictBool = Field(description="If `true`, the statuses of issues being moved in this target group that are not present in the target workflow will be changed to the default status of the target workflow (see below). Leave `targetStatus` empty when using this.  If `false`, you must provide a `targetStatus` for each status not present in the target workflow.  The default status in a workflow is referred to as the \"initial status\". Each workflow has its own unique initial status. When an issue is created, it is automatically assigned to this initial status. Read more about configuring initial statuses: [Configure the initial status | Atlassian Support.](https://support.atlassian.com/jira-cloud-administration/docs/configure-the-initial-status/)", alias="inferStatusDefaults")
    infer_subtask_type_default: StrictBool = Field(description="When an issue is moved, its subtasks (if there are any) need to be moved with it. `inferSubtaskTypeDefault` helps with moving the subtasks by picking a random subtask type in the target project.  If `true`, subtasks will automatically move to the same project as their parent.  When they move:   *  Their `issueType` will be set to the default for subtasks in the target project.  *  Values for mandatory fields will be retained from the source issues  *  Specifying separate mapping for implicit subtasks won’t be allowed.  If `false`, you must manually move the subtasks. They will retain the parent which they had in the current project after being moved.", alias="inferSubtaskTypeDefault")
    issue_ids_or_keys: Optional[List[StrictStr]] = Field(default=None, description="List of issue IDs or keys to be moved. These issues must be from the same project, have the same issue type, and be from the same parent (if they’re subtasks).", alias="issueIdsOrKeys")
    target_classification: Optional[List[Optional[TargetClassification]]] = Field(default=None, description="List of the objects containing classifications in the source issues and their new values which need to be set during the bulk move operation.   *  **You should only define this property when `inferClassificationDefaults` is `false`.**  *  **In order to provide mapping for issues which don't have a classification, use `\"-1\"`.**", alias="targetClassification")
    target_mandatory_fields: Optional[List[Optional[TargetMandatoryFields]]] = Field(default=None, description="List of objects containing mandatory fields in the target field configuration and new values that need to be set during the bulk move operation.  The new values will only be applied if the field is mandatory in the target project and at least one issue from the source has that field empty, or if the field context is different in the target project (e.g. project-scoped version fields).  **You should only define this property when `inferFieldDefaults` is `false`.**", alias="targetMandatoryFields")
    target_status: Optional[List[Optional[TargetStatus]]] = Field(default=None, description="List of the objects containing statuses in the source workflow and their new values which need to be set during the bulk move operation.  The new values will only be applied if the source status is invalid for the target project and issue type.  **You should only define this property when `inferStatusDefaults` is `false`.**", alias="targetStatus")
    __properties: ClassVar[List[str]] = ["inferClassificationDefaults", "inferFieldDefaults", "inferStatusDefaults", "inferSubtaskTypeDefault", "issueIdsOrKeys", "targetClassification", "targetMandatoryFields", "targetStatus"]

    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 TargetToSourcesMapping 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.
        """
        excluded_fields: Set[str] = set([
        ])

        _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 target_classification (list)
        _items = []
        if self.target_classification:
            for _item_target_classification in self.target_classification:
                if _item_target_classification:
                    _items.append(_item_target_classification.to_dict())
            _dict['targetClassification'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in target_mandatory_fields (list)
        _items = []
        if self.target_mandatory_fields:
            for _item_target_mandatory_fields in self.target_mandatory_fields:
                if _item_target_mandatory_fields:
                    _items.append(_item_target_mandatory_fields.to_dict())
            _dict['targetMandatoryFields'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in target_status (list)
        _items = []
        if self.target_status:
            for _item_target_status in self.target_status:
                if _item_target_status:
                    _items.append(_item_target_status.to_dict())
            _dict['targetStatus'] = _items
        # set to None if target_classification (nullable) is None
        # and model_fields_set contains the field
        if self.target_classification is None and "target_classification" in self.model_fields_set:
            _dict['targetClassification'] = None

        # set to None if target_mandatory_fields (nullable) is None
        # and model_fields_set contains the field
        if self.target_mandatory_fields is None and "target_mandatory_fields" in self.model_fields_set:
            _dict['targetMandatoryFields'] = None

        # set to None if target_status (nullable) is None
        # and model_fields_set contains the field
        if self.target_status is None and "target_status" in self.model_fields_set:
            _dict['targetStatus'] = None

        return _dict

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

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

        _obj = cls.model_validate({
            "inferClassificationDefaults": obj.get("inferClassificationDefaults"),
            "inferFieldDefaults": obj.get("inferFieldDefaults"),
            "inferStatusDefaults": obj.get("inferStatusDefaults"),
            "inferSubtaskTypeDefault": obj.get("inferSubtaskTypeDefault"),
            "issueIdsOrKeys": obj.get("issueIdsOrKeys"),
            "targetClassification": [TargetClassification.from_dict(_item) for _item in obj["targetClassification"]] if obj.get("targetClassification") is not None else None,
            "targetMandatoryFields": [TargetMandatoryFields.from_dict(_item) for _item in obj["targetMandatoryFields"]] if obj.get("targetMandatoryFields") is not None else None,
            "targetStatus": [TargetStatus.from_dict(_item) for _item in obj["targetStatus"]] if obj.get("targetStatus") is not None else None
        })
        return _obj


