# SPDX-License-Identifier: Apache-2.0
# 
# Copyright (C) 2024 Acuvity, Inc.
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#     http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Code generated by regolithe-python. DO NOT EDIT.
# Source: github.com/acuvity/regolithe-python (templates/elemental.py.tmpl)


from typing import TypeVar, Optional, Any
from pydantic import BaseModel, ConfigDict, Field, model_validator

try:
    import msgpack
    import msgpack.ext
    HAVE_MSGPACK = True
except ImportError:
    HAVE_MSGPACK = False

class ElementalModel(BaseModel):
    """
    ElementalModel is the base class for all models that were generated from an elemental spec.
    It serves mainly as a marker that all of these classes are models which are derived from elemental.
    However, it also extends this class with utility functions that are useful for all models.
    """
    @model_validator(mode="before")
    def convert_msgpack_timestamps(cls, values):
        """
        This validator runs before any other field-level validation.
        It converts any `msgpack.ext.Timestamp` in the model to a `datetime` object
        so that we can have normal datetime objects in the model and still use msgpack
        and json interchangeably.
        """
        if not HAVE_MSGPACK:
            return values
        else:
            # Iterate through all fields and check for `msgpack.ext.Timestamp`
            for field, value in values.items():
                if isinstance(value, msgpack.ext.Timestamp):
                    # values[field] = datetime.fromtimestamp(value.seconds + value.nanoseconds / 1e9)
                    values[field] = value.to_datetime()
            return values

ElementalObject = TypeVar('ElementalObject', bound=ElementalModel)
RequestElementalObject = TypeVar('RequestElementalObject', bound=ElementalModel)
ResponseElementalObject = TypeVar('ResponseElementalObject', bound=ElementalModel)

class ElementalError(ElementalModel):
    """
    ElementalError represents the model of an error
    """
    model_config = ConfigDict(strict=False)

    code: Optional[int] = Field(None, description="Optional error code.")
    description: str = Field(..., description="The error description.")
    subject: str = Field(..., description="The error subject.")
    title: str = Field(..., description="The error title.")
    data: Optional[Any] = Field(None, description="Optional additional error data.")
    trace: Optional[str] = Field(None, description="Optional error trace.")
