import typing, abc
from System import IDisposable, Array_1
from TransformsAI.Animo.Data.Database.Tables import AgentTable, CheckpointTable, LevelTable
from TransformsAI.Animo.Data.Models import CheckpointId, CheckpointData

class AnimoDatabase(IDisposable, abc.ABC):
    Current : AnimoDatabase
    MaximumSavedBrainCount : int
    @property
    def Agents(self) -> AgentTable: ...
    @property
    def Checkpoints(self) -> CheckpointTable: ...
    @property
    def Levels(self) -> LevelTable: ...
    @property
    def Models(self) -> IModelSource: ...
    @abc.abstractmethod
    def Clear(self) -> None: ...
    def Dispose(self) -> None: ...


class FilePaths:
    def __init__(self, databaseDirectory: str) -> None: ...
    AgentsDirectory : str
    DatabaseDirectory : str
    LevelsDirectory : str
    SessionsDirectory : str
    def FilePathToAgentId(self, filePath: str) -> str: ...
    def FilePathToLevelId(self, filePath: str) -> str: ...
    def GetAgentCheckpointsDirectory(self, agentId: int) -> str: ...
    def GetAgentDataFilePath(self, agentId: int) -> str: ...
    def GetAgentDirectory(self, agentId: int) -> str: ...
    def GetCheckpointDirectory(self, agentId: int, timestamp: int) -> str: ...
    def GetCheckpointFilePath(self, agentId: int, timestamp: int) -> str: ...
    def GetLevelFilePath(self, levelId: str) -> str: ...
    def GetModelFilePath(self, agentId: int, timestamp: int) -> str: ...
    def GetRewardFilePath(self, agentId: int, timestamp: int) -> str: ...
    def GetSessionDirectory(self, sessionId: str) -> str: ...
    def Initialize(self) -> None: ...


class FileSystemDatabase(AnimoDatabase, IModelSource):
    def __init__(self, paths: FilePaths) -> None: ...
    Paths : FilePaths
    @property
    def Agents(self) -> AgentTable: ...
    @property
    def Checkpoints(self) -> CheckpointTable: ...
    @classmethod
    @property
    def Current(cls) -> FileSystemDatabase: ...
    @property
    def Levels(self) -> LevelTable: ...
    @property
    def Models(self) -> IModelSource: ...
    def Clear(self) -> None: ...
    def Initialize(self) -> None: ...
    def LoadRawCheckpoint(self, cpId: CheckpointId) -> Array_1[int]: ...
    def LoadRawModel(self, cpId: CheckpointId) -> Array_1[int]: ...
    def SaveModelAndCheckpoint(self, cp: CheckpointData, modelData: Array_1[int], checkpointData: Array_1[int]) -> None: ...
    def Synchronize(self) -> None: ...


class IModelSource(typing.Protocol):
    @abc.abstractmethod
    def LoadRawCheckpoint(self, id: CheckpointId) -> Array_1[int]: ...
    @abc.abstractmethod
    def LoadRawModel(self, id: CheckpointId) -> Array_1[int]: ...
    @abc.abstractmethod
    def SaveModelAndCheckpoint(self, cp: CheckpointData, modelData: Array_1[int], checkpointData: Array_1[int]) -> None: ...


class ModificationType(typing.SupportsInt):
    @typing.overload
    def __init__(self, value : int) -> None: ...
    @typing.overload
    def __init__(self, value : int, force_if_true: bool) -> None: ...
    def __int__(self) -> int: ...
    
    # Values:
    Insert : ModificationType # 0
    Update : ModificationType # 1
    Delete : ModificationType # 2
    Replace : ModificationType # 3

