from typing import TypeVar
from abc import ABCMeta, abstractmethod
from scipy import linalg as linalg
from numpy import ndarray
from ..base import BaseEstimator, TransformerMixin, ClassNamePrefixFeaturesOutMixin
from .._typing import MatrixLike
from ..utils.validation import check_is_fitted as check_is_fitted

_BasePCA_Self = TypeVar("_BasePCA_Self", bound="_BasePCA")


# Author: Alexandre Gramfort <alexandre.gramfort@inria.fr>
#         Olivier Grisel <olivier.grisel@ensta.org>
#         Mathieu Blondel <mathieu@mblondel.org>
#         Denis A. Engemann <denis-alexander.engemann@inria.fr>
#         Kyle Kastner <kastnerkyle@gmail.com>
#
# License: BSD 3 clause

import numpy as np


class _BasePCA(
    ClassNamePrefixFeaturesOutMixin, TransformerMixin, BaseEstimator, metaclass=ABCMeta
):
    def get_covariance(self) -> ndarray:
        ...

    def get_precision(self) -> ndarray:
        ...

    @abstractmethod
    def fit(self: _BasePCA_Self, X: MatrixLike, y=None) -> _BasePCA_Self:
        ...

    def transform(self, X: MatrixLike) -> ndarray:
        ...

    def inverse_transform(self, X: MatrixLike) -> ndarray:
        ...
