# This code is part of Qiskit.
#
# (C) Copyright IBM 2023.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""
Entry for artifact data.
"""

from dataclasses import dataclass, field
from typing import Any, Optional, List
from datetime import datetime
import uuid

from dateutil import tz


@dataclass
class ArtifactData:
    """A dataclass for non-analysis result payloads in :class:`.ExperimentData` objects.

    This class can convert results generated by the analysis class into a payload
    for saving and retrieving to and from the experiments service, which stores this
    as artifacts. Types of objects that may be converted to artifacts include fitted and raw data,
    fit status, and any other JSON-based data needed to serialize experiments and experiment data.

    Attributes:
        name: The name of the artifact. When saved to the cloud service, this will be the name
            of the zipfile this artifact object is stored in.
        data: The artifact payload.
        artifact_id: Artifact ID. Must be unique inside an :class:`ExperimentData` object.
        experiment_id: Experiment ID that the artifact is associated with.
        experiment: The name of the experiment.
        device_components: The device components of the experiment.
        created_time: Time when the artifact was created.
    """

    name: str
    data: Any
    artifact_id: Optional[str] = field(default_factory=lambda: str(uuid.uuid4()))
    experiment_id: Optional[str] = None
    experiment: Optional[str] = None
    device_components: List = field(default_factory=list)
    created_time: Optional[datetime] = field(default_factory=lambda: datetime.now(tz.tzlocal()))

    @property
    def dtype(self):
        """Data type of the payload."""
        return self.data.__class__.__name__

    def __repr__(self):
        return (
            f"ArtifactData(name={self.name}, dtype={self.dtype}, uid={self.artifact_id}, "
            f"experiment={self.experiment}, device_components={self.device_components})"
        )
