# Copyright (C) 2023 Cochise Ruhulessin
#
# All rights reserved. No warranty, explicit or implicit, provided. In
# no event shall the author(s) be liable for any claim or damages.
#
# 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.
from __future__ import annotations
import datetime
import uuid
from typing import Any
from typing import TYPE_CHECKING

import pydantic

if TYPE_CHECKING:
    from .resource import Resource
from .resourcekey import ResourceKey


class TransientMeta(pydantic.BaseModel):
    model_config = {'populate_by_name': True}

    annotations: dict[str, Any] = pydantic.Field(
        default_factory=dict,
        title="Annotations",
        description=(
            "Annotations is an unstructured key value map stored with "
            "a resource that may be set by external tools to store "
            "and retrieve arbitrary metadata. They are not queryable and "
            "should be preserved when modifying objects."
        )
    )
    
    created: datetime.datetime | None = pydantic.Field(
        default_factory=lambda: datetime.datetime.now(datetime.timezone.utc),
        title="Created",
        description=(
            "`created` is a timestamp representing the server time "
            "when this object was created. It is not guaranteed to be set in "
            "happens-before order across separate operations. Clients may not "
            "set this value. It is represented in RFC3339 form and is in UTC. "
            "Populated by the system. Read-only. Null for lists."
        ),
        frozen=True
    )

    labels: dict[str, str | None] = pydantic.Field(
        default_factory=dict,
        title="Labels",
        description=(
            "Map of string keys and values that can be used to organize and "
            "categorize (scope and select) objects."
        )
    )

    tags: set[str] = pydantic.Field(
        default_factory=set,
        description=(
            "An array of tags that may be used to classify an object "
            "if a label or annotation is not applicable."
        )
    )

    uid: str = pydantic.Field(
        default_factory=lambda: str(uuid.uuid4()),
        title="UID",
        description=(
            "UID is the unique in time and space value for this object. "
            "It is typically generated by the server on successful creation "
            "of a resource and is not allowed to change on PUT operations. "
            "Populated by the system. Read-only."
        ),
        frozen=True
    )

    @classmethod
    def is_namespaced(cls) -> bool:
        return False

    @classmethod
    def default(cls):
        return cls()

    @property
    def name(self) -> str:
        raise NotImplementedError

    @property
    def key(self) -> ResourceKey[Any]:
        raise NotImplementedError

    @property
    def resource_version(self) -> None:
        return None

    def attach(self, resource: Resource[Any]):
        self._api_version = resource.api_version
        self._kind = resource.kind

    def get_namespace(self) -> str | None:
        return None

    def update_resource_version(self, obj: Resource[Any]):
        pass