# coding: utf-8

"""
    University Photo API

     ## Introduction  The Photo API allows access to Photos of members of the University. The Photos exposed by this API are expected to be a good representation of the person they relate to.  The API broadly follows the principles of REST and strives to provide an interface that can be easily consumed by downstream systems.  ### Stability  This release of the Photo API is a `beta` offering: a service we are moving towards live but which requires wider testing with a broader group of users.  ### Versioning  The Photo API is versioned using URL path prefixes in the format: `/v1beta1/photos`. This follows the pattern established by the [GCP API](https://cloud.google.com/apis/design/versioning). Breaking changes will not be made without a change in API major version, however non-breaking changes will be introduced without changes to the version path prefix. All changes will be documented in the project's [CHANGELOG](https://gitlab.developers.cam.ac.uk/uis/devops/iam/photo-api/-/blob/master/CHANGELOG.md)  The available versions of the API are listed at the API's root.  ### Domain  The Photo API serves Photos of members of the University, linking a Photo to an individual through `PhotoIdentifiers` (see below) which pertain to a person record within an external system.  The Photos served by the Photo API are expected to be of sufficient quality to identify the person they represent. Photos which have been reviewed and determined to be sufficient quality are marked as having the status `approved` and exposed through the `approved-photos` endpoints.  ### Data source  The Photos exposed by the Photo API are currently a mirror of card Photos contained within the [Card Database](https://webservices.admin.cam.ac.uk/uc/). With Photos being synced from the Card Database to the Photo API hourly.  In future, the Photo API will be extended to allow Photos to be created and 'approved' using the API.  ## Core entities  ### The `Photo` Entity  The `Photo` entity contains information and metadata about a Photo of a member of the university. The `status` field on a Photo indicates whether this Photo has been reviewed and approved. Only Photos which have the status `approved` are exposed through the `approved-photos` endpoints. Each photo entity has a unique identifier - termed UUID - which is used in the system to refer to the specific photo entity. The UUID is provided in JSON documents as the `id` property.   Each Photo entity contains a link to the image data itself and a thumbnail for this Photo, which is guaranteed to be less than 128x128 pixels. Images are served by redirecting to a temporary URL provided by the service used to host images. These temporary URLs will expire after an hour and should not be retained for long-lasting access to a given Photo.  Each Photo may contain a block of JSON metadata recording information about the Photo. Photos cannot be updated once created (apart from to move their status to `approved`) hence this metadata should not be used to store application state or any other information which is not related to the content of the Photo.  Each Photo will have a set of `PhotoIdentifier` which allow the Photo to be linked to a person record within another system.  ### The `PhotoIdentifier` Entity  The `PhotoIdentifier` entity holds the `value` and `scheme` of a given identifier. The `value` field of a `PhotoIdentifier` is a simple ID string - e.g. `wgd23` or `000001`. The `scheme` field of a `PhotoIdentifier` indicates what system this identifier relates to or was issued by. This allows many identifiers which relate to different systems to be recorded against a single `Photo`.  The supported schemes are: * `v1.person.identifiers.cam.ac.uk`: The CRSID of the person represented by this Photo * `person.v1.student-records.university.identifiers.cam.ac.uk`: The CamSIS identifier (USN) of the person represented by this Photo * `person.v1.human-resources.university.identifiers.cam.ac.uk`: The CHRIS identifier (staff number) of the person represented by this Photo * `photo.v1.legacy-card.university.identifiers.cam.ac.uk`: The id of this Photo within the legacy card system  ## Using the API  ### Auth  To authenticate against the Photo API, an application must be registered within the API Gateway and granted access to the `University Photo` product. Details of how to register an application and grant access to products can be found in the [API Gateway Getting Started Guide](https://developer.api.apps.cam.ac.uk/start-using-an-api).  

    The version of the OpenAPI document: v1beta1
    Contact: devops+photoapi@uis.cam.ac.uk
    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 datetime import datetime
from typing import Any, Dict, List, Optional
from pydantic import BaseModel, Field, StrictInt, StrictStr, conlist
from identitylib.photo_client.models.status_enum import StatusEnum
from identitylib.photo_client.models.v1_beta1_photo_identifier_summary import V1Beta1PhotoIdentifierSummary

class V1Beta1Photo(BaseModel):
    """
    V1Beta1Serializer is the same as the V1Alpha1 version, except for directly returning the identifiers rather than mapping their schemes back to deprecated forms.
    """
    approved_at: Optional[datetime] = Field(None, alias="approvedAt", description="If non-NULL, when this photo was approved as being a good representation of the person it relates to")
    approved_by: Optional[StrictStr] = Field(None, alias="approvedBy", description="The identifier of the user who approved this photo - may not be known for legacy data")
    content_link: StrictStr = Field(..., alias="contentLink")
    created_at: datetime = Field(..., alias="createdAt", description="When this record was created")
    id: StrictStr = Field(...)
    identifiers: conlist(V1Beta1PhotoIdentifierSummary) = Field(...)
    image_height: Optional[StrictInt] = Field(..., alias="imageHeight", description="The height of the image")
    image_width: Optional[StrictInt] = Field(..., alias="imageWidth", description="The width of the image")
    invalidated_at: Optional[datetime] = Field(None, alias="invalidatedAt", description="If non-NULL, the date & time that the photo was invalidated")
    invalidated_by: Optional[StrictStr] = Field(None, alias="invalidatedBy", description="The identifier of the user who invalidated this photo.")
    metadata: Optional[Dict[str, Any]] = Field(None, description="A freeform block of JSON metadata related to this photo")
    original_link: StrictStr = Field(..., alias="originalLink")
    review_postponed_at: Optional[datetime] = Field(None, alias="reviewPostponedAt", description="If non-NULL, the date & time that the photo was last skipped during review process")
    self_link: StrictStr = Field(..., alias="selfLink")
    status: StatusEnum = Field(...)
    submitted_by: StrictStr = Field(..., alias="submittedBy", description="The identifier of the user who submitted this photo if submitted by a user, else the name of the automated process or system")
    thumbnail_link: StrictStr = Field(..., alias="thumbnailLink")
    updated_at: Optional[datetime] = Field(None, alias="updatedAt", description="When this photo was last updated.")
    updated_by: Optional[StrictStr] = Field(None, alias="updatedBy", description="The identifier of the user who updated this photo.")
    __properties = ["approvedAt", "approvedBy", "contentLink", "createdAt", "id", "identifiers", "imageHeight", "imageWidth", "invalidatedAt", "invalidatedBy", "metadata", "originalLink", "reviewPostponedAt", "selfLink", "status", "submittedBy", "thumbnailLink", "updatedAt", "updatedBy"]

    class Config:
        """Pydantic configuration"""
        allow_population_by_field_name = True
        validate_assignment = True

    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.dict(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> V1Beta1Photo:
        """Create an instance of V1Beta1Photo from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self):
        """Returns the dictionary representation of the model using alias"""
        _dict = self.dict(by_alias=True,
                          exclude={
                            "content_link",
                            "created_at",
                            "id",
                            "image_height",
                            "image_width",
                            "original_link",
                            "self_link",
                            "thumbnail_link",
                          },
                          exclude_none=True)
        # override the default output from pydantic by calling `to_dict()` of each item in identifiers (list)
        _items = []
        if self.identifiers:
            for _item in self.identifiers:
                if _item:
                    _items.append(_item.to_dict())
            _dict['identifiers'] = _items
        # set to None if approved_at (nullable) is None
        # and __fields_set__ contains the field
        if self.approved_at is None and "approved_at" in self.__fields_set__:
            _dict['approvedAt'] = None

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

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

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

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

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

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

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

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

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

        return _dict

    @classmethod
    def from_dict(cls, obj: dict) -> V1Beta1Photo:
        """Create an instance of V1Beta1Photo from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return V1Beta1Photo.parse_obj(obj)

        _obj = V1Beta1Photo.parse_obj({
            "approved_at": obj.get("approvedAt"),
            "approved_by": obj.get("approvedBy"),
            "content_link": obj.get("contentLink"),
            "created_at": obj.get("createdAt"),
            "id": obj.get("id"),
            "identifiers": [V1Beta1PhotoIdentifierSummary.from_dict(_item) for _item in obj.get("identifiers")] if obj.get("identifiers") is not None else None,
            "image_height": obj.get("imageHeight"),
            "image_width": obj.get("imageWidth"),
            "invalidated_at": obj.get("invalidatedAt"),
            "invalidated_by": obj.get("invalidatedBy"),
            "metadata": obj.get("metadata"),
            "original_link": obj.get("originalLink"),
            "review_postponed_at": obj.get("reviewPostponedAt"),
            "self_link": obj.get("selfLink"),
            "status": obj.get("status"),
            "submitted_by": obj.get("submittedBy"),
            "thumbnail_link": obj.get("thumbnailLink"),
            "updated_at": obj.get("updatedAt"),
            "updated_by": obj.get("updatedBy")
        })
        return _obj


