from enum import StrEnum
from pathlib import Path  # noqa: TC003 (required by pydantic at runtime)
from typing import TypeVar

from pydantic import BaseModel, ConfigDict


class Base(BaseModel):
    """TODO."""

    model_config = ConfigDict(extra="forbid")


class FuzzForgeModulesSettingsBase(Base):
    """TODO."""


FuzzForgeModulesSettingsType = TypeVar("FuzzForgeModulesSettingsType", bound=FuzzForgeModulesSettingsBase)


class FuzzForgeModuleResources(StrEnum):
    """Enumeration of artifact types."""

    #: The type of the resource is unknown or irrelevant.
    UNKNOWN = "unknown"


class FuzzForgeModuleResource(Base):
    """TODO."""

    #: The description of the resource.
    description: str
    #: The type of the resource.
    kind: FuzzForgeModuleResources
    #: The name of the resource.
    name: str
    #: The path of the resource on disk.
    path: Path


class FuzzForgeModuleInputBase[FuzzForgeModulesSettingsType: FuzzForgeModulesSettingsBase](Base):
    """The (standardized) input of a FuzzForge module."""

    #: The collection of resources given to the module as inputs.
    resources: list[FuzzForgeModuleResource]
    #: The settings of the module.
    settings: FuzzForgeModulesSettingsType


class FuzzForgeModuleArtifacts(StrEnum):
    """Enumeration of artifact types."""

    #: The artifact is an asset.
    ASSET = "asset"


class FuzzForgeModuleArtifact(Base):
    """An artifact generated by the module during its run."""

    #: The description of the artifact.
    description: str
    #: The type of the artifact.
    kind: FuzzForgeModuleArtifacts
    #: The name of the artifact.
    name: str
    #: The path to the artifact on disk.
    path: Path


class FuzzForgeModuleResults(StrEnum):
    """TODO."""

    SUCCESS = "success"
    FAILURE = "failure"


class FuzzForgeModuleOutputBase(Base):
    """The (standardized) output of a FuzzForge module."""

    #: The collection of artifacts generated by the module during its run.
    artifacts: list[FuzzForgeModuleArtifacts]
    #: The path to the logs.
    logs: Path
    #: The result of the module's run.
    result: FuzzForgeModuleResults
