from typing import Any, Dict, Optional
from copy import deepcopy
from api.io_port import DType


class Asset:
    """
    Represents the output of a Task.

    Stores:
    - data: actual payload
    - dtype: semantic type (DType instance)
    - metadata: optional dictionary
    """

    def __init__(self, data: Any, dtype: Optional[DType] = None, metadata: Optional[Dict[str, Any]] = None):
        self.data = data
        self.dtype = dtype              # DO NOT deepcopy dtype
        self.metadata = metadata or {}

        # Whether this asset should be preserved after workflow execution
        self.preserved = True

    # Lifecycle
    def dismiss(self):
        """Mark asset as disposable."""
        self.preserved = False

    # Utility
    def clone(self) -> "Asset":
        """
        Create a deep copy of the asset.
        dtype is NOT deepcopied because DType objects are not deepcopy-safe.
        """
        return Asset(
            data=deepcopy(self.data),
            dtype=self.dtype,                     # keep reference
            metadata=deepcopy(self.metadata)
        )

    # Representation
    def __repr__(self):
        # Avoid printing full dtype object (may contain nested structures)
        dtype_name = self.dtype.__class__.__name__ if self.dtype else "None"
        return f"<Asset dtype={dtype_name} preserved={self.preserved}>"
