# isort:skip_file
import abc
from abc import ABC, abstractmethod
from datetime import datetime
from pathlib import Path
from typing import Any, Optional

import pandas as pd  # type: ignore

from pullframe.types import CacheFormat as CacheFormat
from pullframe.types import Demand as Demand
from pullframe.types import Node as Node
from pullframe.types import Request as Request
from pullframe.types import Resource as Resource

class Persist(ABC, metaclass=abc.ABCMeta):
    directory: Path = ...
    def __init__(self, directory: Path) -> None: ...
    def on(cls: Any, directory: Path) -> "Persist": ...
    @abstractmethod
    def load(
        self,
        name: str,
        start: Optional[datetime] = ...,
        end: Optional[datetime] = ...,
        include_start: bool = ...,
    ) -> pd.DataFrame: ...
    @abstractmethod
    def save(self, name: str, df: pd.DataFrame) -> None: ...
    @abstractmethod
    def exists(self, name: str) -> bool: ...
    @abstractmethod
    def last_index(self, name: str) -> datetime: ...
    @abstractmethod
    def update(self, name: str, path: Path) -> None: ...
    def format(cls: Any) -> CacheFormat: ...
    @staticmethod
    @abstractmethod
    def suffix() -> str: ...
    def version(self, name: str) -> Optional[int]: ...
    def set_version(self, name: str, version: int) -> None: ...
    def supply(self, demand: Demand, include_start: bool) -> pd.DataFrame: ...
    def version_path(self, name: str) -> Path: ...
    def path(self, name: str) -> Path: ...
    def dump_path(self, request: Request) -> Any: ...

class Coordinator(ABC, metaclass=abc.ABCMeta):
    @abstractmethod
    def available(
        self, name: str, last_idx: Optional[datetime], version: int
    ) -> Optional[Resource]: ...
    @abstractmethod
    def notify(
        self, name: str, node: Node, version: int, last_idx: datetime
    ) -> None: ...
    @abstractmethod
    def version(self, name: str) -> Optional[int]: ...
