# coding: utf-8

"""
    University Human Resources API

    This API exposes identity information from the University Human Resources system. The purpose of this API is to give access to basic identity information about staff members for use by downstream systems, therefore the data exposed is limited to basic information about who a staff member is and details of any affiliations they have.  This API uses the following identifiers to link people to person-records held within different systems:  * `person.v1.human-resources.university.identifiers.cam.ac.uk` - the university human resources (uhr) identifier of     this person - also known as the staff number of HRN. * `v1.person.identifiers.cam.ac.uk` - the common registration scheme identifier (CRSid) of     this person.  Additionally this API uses the following identifiers to link people to institutions or entities which a person may have an affiliation to:  * `institution.v1.human-resources.university.identifiers.cam.ac.uk` - the university human resources (uhr) institution     identifier. This encompasses departments within the University HR system     (currently CHRIS). * `institution.v1.student-records.university.identifiers.cam.ac.uk` - the student records institution identifier. This     encompasses colleges within the University Student Records system (currently CamSIS).  Affiliations can be used to indicate an institution that a person holds a position within, with the `status` indicating the job role that is held and the scheme of the affiliation being `institution.v1.human-resources.university.identifiers.cam.ac.uk`. Additionally an affiliation can indicate a staff member's line manager with the scheme being `person.v1.human-resources.university.identifiers.cam.ac.uk` and the status being `report`. A staff member can have multiple institution affiliations and multiple report affiliations.  This API is currently backed by data from CHRIS, exposing a view which is updated hourly.  

    The version of the OpenAPI document: v1alpha2
    Generated by OpenAPI Generator (https://openapi-generator.tech)

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


from __future__ import annotations
from inspect import getfullargspec
import json
import pprint
import re  # noqa: F401
from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, ValidationError, field_validator
from typing import Optional
from typing import Union, Any, List, Set, TYPE_CHECKING, Optional, Dict
from typing_extensions import Literal, Self
from pydantic import Field

LOCATIONINNER_ANY_OF_SCHEMAS = ["int", "str"]

class LocationInner(BaseModel):
    """
    LocationInner
    """

    # data type: str
    anyof_schema_1_validator: Optional[StrictStr] = None
    # data type: int
    anyof_schema_2_validator: Optional[StrictInt] = None
    if TYPE_CHECKING:
        actual_instance: Optional[Union[int, str]] = None
    else:
        actual_instance: Any = None
    any_of_schemas: Set[str] = { "int", "str" }

    model_config = {
        "validate_assignment": True,
        "protected_namespaces": (),
    }

    def __init__(self, *args, **kwargs) -> None:
        if args:
            if len(args) > 1:
                raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`")
            if kwargs:
                raise ValueError("If a position argument is used, keyword arguments cannot be used.")
            super().__init__(actual_instance=args[0])
        else:
            super().__init__(**kwargs)

    @field_validator('actual_instance')
    def actual_instance_must_validate_anyof(cls, v):
        instance = LocationInner.model_construct()
        error_messages = []
        # validate data type: str
        try:
            instance.anyof_schema_1_validator = v
            return v
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # validate data type: int
        try:
            instance.anyof_schema_2_validator = v
            return v
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        if error_messages:
            # no match
            raise ValueError("No match found when setting the actual_instance in LocationInner with anyOf schemas: int, str. Details: " + ", ".join(error_messages))
        else:
            return v

    @classmethod
    def from_dict(cls, obj: Dict[str, Any]) -> Self:
        return cls.from_json(json.dumps(obj))

    @classmethod
    def from_json(cls, json_str: str) -> Self:
        """Returns the object represented by the json string"""
        instance = cls.model_construct()
        error_messages = []
        # deserialize data into str
        try:
            # validation
            instance.anyof_schema_1_validator = json.loads(json_str)
            # assign value to actual_instance
            instance.actual_instance = instance.anyof_schema_1_validator
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # deserialize data into int
        try:
            # validation
            instance.anyof_schema_2_validator = json.loads(json_str)
            # assign value to actual_instance
            instance.actual_instance = instance.anyof_schema_2_validator
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))

        if error_messages:
            # no match
            raise ValueError("No match found when deserializing the JSON string into LocationInner with anyOf schemas: int, str. Details: " + ", ".join(error_messages))
        else:
            return instance

    def to_json(self) -> str:
        """Returns the JSON representation of the actual instance"""
        if self.actual_instance is None:
            return "null"

        if hasattr(self.actual_instance, "to_json") and callable(self.actual_instance.to_json):
            return self.actual_instance.to_json()
        else:
            return json.dumps(self.actual_instance)

    def to_dict(self) -> Optional[Union[Dict[str, Any], int, str]]:
        """Returns the dict representation of the actual instance"""
        if self.actual_instance is None:
            return None

        if hasattr(self.actual_instance, "to_dict") and callable(self.actual_instance.to_dict):
            return self.actual_instance.to_dict()
        else:
            return self.actual_instance

    def to_str(self) -> str:
        """Returns the string representation of the actual instance"""
        return pprint.pformat(self.model_dump())


