from typing import Dict, List, TypeVar, Union

from dtaianomaly.anomaly_detection import BaseDetector
from dtaianomaly.evaluation import BinaryMetric, Metric, ProbaMetric, ThresholdMetric
from dtaianomaly.pipeline import EvaluationPipeline
from dtaianomaly.preprocessing import Preprocessor
from dtaianomaly.thresholding import Thresholding

T = TypeVar("T")


def build_pipelines(
    preprocessors: List[Preprocessor],
    detectors: List[BaseDetector],
    metrics: List[ProbaMetric],
) -> List[EvaluationPipeline]:
    """The given lists are assumed to be non-empty."""
    return [
        EvaluationPipeline(
            preprocessor=preprocessor, detector=detector, metrics=metrics
        )
        for preprocessor in preprocessors
        for detector in detectors
    ]


def convert_to_proba_metrics(
    metrics: List[Metric], thresholds: List[Thresholding]
) -> List[ProbaMetric]:
    """The given lists are assumed to be non-empty."""
    proba_metrics = []
    for metric in metrics:
        if isinstance(metric, BinaryMetric):
            proba_metrics.extend(
                ThresholdMetric(thresholder=threshold, metric=metric)
                for threshold in thresholds
            )
        elif isinstance(metric, ProbaMetric):
            proba_metrics.append(metric)
    return proba_metrics


def convert_to_list(value: Union[T, List[T]]) -> List[T]:
    """If a list is given, it is assumed to be non-empty."""
    if not isinstance(value, list):
        return [
            value,
        ]
    return value
