# coding: utf-8

"""
    File Service API v2

    File Service API v2 - Main endpoints (excludes token and tenant management)

    The version of the OpenAPI document: 0.1.0
    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, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from istari_digital_client.v2.models.content import Content
from typing import Optional, Set
from typing_extensions import Self

class UpdateDocumentRequest(BaseModel):
    """
    Request for updating an existing document with selective field updates.  This provides a flexible API for document updates. Provide only the fields you want to change - the backend automatically creates a new revision while preserving unchanged fields from the base revision.  **Design Philosophy:** Updates should be simple and intuitive. Whether you're making a small typo fix (content only), renaming a document (name only), or doing a major rewrite (all fields), the API stays consistent and easy to use.  **Revision-Based Updates:** By default, updates are based on the current (latest) revision. However, you can explicitly specify a `revision_id` to update from a specific older revision. This is useful when: - You're viewing a historical version and want to update from that point - You want to prevent accidental overwrites of recent changes - You need explicit conflict detection  Attributes ----------     content: New ProseMirror content as dict or JSON string.             If omitted, content remains unchanged from the base revision.     name: New document name.           If omitted, name remains unchanged from the base revision.     description: New description.                 If omitted, description remains unchanged from the base revision.     revision_id: Optional file revision ID to use as the base for this update.                 If omitted, uses the current (latest) revision.                 If provided, the specified revision becomes the base, and unchanged                 fields are preserved from that revision rather than the current one.  Note:     At least one content field (content, name, or description) must be provided.     An empty update will return an error.  Examples --------     Update from current revision (default):         >>> request = UpdateDocumentRequest(         ...     content={\"type\": \"doc\", \"content\": [         ...         {\"type\": \"paragraph\", \"content\": [         ...             {\"type\": \"text\", \"text\": \"Updated text\"}         ...         ]}         ...     ]}         ... )      Update from a specific older revision:         >>> request = UpdateDocumentRequest(         ...     revision_id=UUID(\"older-revision-id\"),         ...     content={\"type\": \"doc\", \"content\": [         ...         {\"type\": \"paragraph\", \"content\": [         ...             {\"type\": \"text\", \"text\": \"Changes based on old version\"}         ...         ]}         ...     ]}         ... )      Rename only:     >>> request = UpdateDocumentRequest(         ...     name=\"Requirements v2\"     ... )
    """ # noqa: E501
    content: Optional[Content] = None
    name: Optional[StrictStr] = None
    description: Optional[StrictStr] = None
    revision_id: Optional[StrictStr] = None
    __properties: ClassVar[List[str]] = ["content", "name", "description", "revision_id"]

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


    def to_str(self) -> str:
        """
        Return the string representation of the model using field aliases.

        This method serializes the model to a JSON-formatted string, respecting any defined aliases
        for fields instead of their original attribute names.
        """

        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """
        Return the JSON string representation of the model using field aliases.

        This method serializes the model into a JSON-formatted string, using aliases for field names
        where defined instead of their raw attribute names.
        """

        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """
        Create an instance of the model from a JSON string.

        This method deserializes the given JSON string into a model instance. It expects the
        string to match the model's schema, using field aliases where applicable.

        :param json_str: JSON string representing the model.
        :type json_str: str
        """

        return cls.from_dict(json.loads(json_str))

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

        This method differs from calling `self.model_dump(by_alias=True)` in the following way:

        - Fields with a value of `None` are included in the output only if they are nullable and
          were explicitly set during model initialization. All other `None` fields are omitted.
        """

        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 content
        if self.content:
            _dict['content'] = self.content.to_dict()
        # set to None if content (nullable) is None
        # and model_fields_set contains the field
        if self.content is None and "content" in self.model_fields_set:
            _dict['content'] = None

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

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

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

        return _dict

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

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

        _obj = cls.model_validate({
            "content": Content.from_dict(obj["content"]) if obj.get("content") is not None else None,
            "name": obj.get("name"),
            "description": obj.get("description"),
            "revision_id": obj.get("revision_id")
        })
        return _obj
