"""
Tafra: a minimalist dataframe

Copyright (c) 2020 Derrick W. Turk and David S. Fulford

Author
------
Derrick W. Turk
David S. Fulford

Notes
-----
Created on April 25, 2020
"""
from __future__ import annotations

import numpy as np
from typing import Any, Iterable, Iterator
from typing_extensions import Protocol, runtime_checkable


@runtime_checkable
class Series(Protocol):
    name: str
    values: np.ndarray[Any, Any]
    dtype: str


@runtime_checkable
class DataFrame(Protocol):
    """
    A fake class to satisfy typing of a ``pandas.DataFrame`` without a dependency.
    """
    _data: dict[str, Series]
    columns: list[str]
    dtypes: list[str]

    def __getitem__(self, column: str) -> Series:
        raise NotImplementedError

    def __setitem__(self, column: str, value: np.ndarray[Any, Any]) -> None:
        raise NotImplementedError

@runtime_checkable
class Cursor(Protocol):
    """
    A fake class to satisfy typing of a ``pyodbc.Cursor`` without a dependency.
    """
    description: tuple[tuple[str, type[Any], int | None, int, int, int, bool]]

    def __iter__(self) -> Iterator[tuple[Any, ...]]:
        raise NotImplementedError

    def __next__(self) -> tuple[Any, ...]:
        raise NotImplementedError

    def execute(self, sql: str) -> None:
        raise NotImplementedError

    def fetchone(self) -> tuple[Any, ...] | None:
        raise NotImplementedError

    def fetchmany(self, size: int) -> list[tuple[Any, ...]]:
        raise NotImplementedError

    def fetchall(self) -> list[tuple[Any, ...]]:
        raise NotImplementedError
