from typing import List
from typing import Dict
from typing import Tuple
import collections


def get_dataset_stats(sample_list: List[str],
                      sample_to_study: Dict[str, str],
                      sample_metadata: dict,
                      sample_to_label: Dict[str, str]) -> Tuple[collections.Counter,
                                                                collections.Counter,
                                                                collections.Counter,
                                                                dict]:
    """
    Calculate statistics about a list of samples

    Arguments
    ---------
    sample_list: A list of sample ids to calculate statistics for
    sample_to_study: A mapping from sample ids to study ids
    sample_metadata: A dictionary containing metadata about samples
    sample_to_label: a mapping from sample ids to disease labels

    Returns
    -------
    studies: The number of samples in each study id
    platforms: The number of samples using each expression quantification platform
    diseases: The number of samples labeled with each disease
    study_disease_counts: The number of samples corresponding to each disease in each study
    """
    studies = []
    platforms = []
    diseases = []
    study_disease_counts = {}

    for sample in sample_list:
        study = sample_to_study[sample]
        studies.append(study)
        platform = sample_metadata[sample]['refinebio_platform'].lower()
        platforms.append(platform)

        disease = sample_to_label[sample]
        diseases.append(disease)

        if study in study_disease_counts:
            study_disease_counts[study][disease] = study_disease_counts[study].get(disease, 0) + 1
        else:
            study_disease_counts[study] = {disease: 1}

    studies = collections.Counter(studies)
    platforms = collections.Counter(platforms)
    diseases = collections.Counter(diseases)

    return studies, platforms, diseases, study_disease_counts