"""
Datum
└── Documentation = https://aiqc.readthedocs.io/en/latest/notebooks/datasets.html

- Example datasets that are used for both tutorials and tests.
- Either included in the aiqc package `aiqc/data` or stored remotely `/remote_datum`
"""
#`importlib.resources` was not working on Google Collab.
from pkg_resources import resource_filename 
import pandas as pd


def list_datums(format:str=None):
    """
    - Of course, these could be classes, but record format let's us display all of the info in a dataframe.
    - 'name' value cannot include 'https' because that's how remote datasets are detected.
    """
    records = [
        dict(
            name = 'exoplanets.parquet'
            , dataset_type  = 'tabular'
            , analysis_type = 'regression'
            , label         = 'SurfaceTempK'
            , label_classes = 'N/A'
            , features      = 8
            , samples       = 433
            , description   = 'Predict temperature of exoplanet.'
            , location      = 'local'
        ),
        dict(
            name            = 'heart_failure.parquet'
            , dataset_type  = 'tabular'
            , analysis_type = 'regression'
            , label         = 'died'
            , label_classes = '2'
            , features      = 12
            , samples       = 299
            , description   = "Biometrics to predict loss of life."
            , location      = 'local'
        ),
        dict(
            name            = 'iris.tsv'
            , dataset_type  = 'tabular'
            , analysis_type = 'classification_multi'
            , label         = 'species'
            , label_classes = 3
            , features      = 4
            , samples       = 150
            , description   = '3 species of flowers. Only 150 rows, so cross-folds not represent population.'
            , location      = 'local'
        ),
        dict(
            name            = 'sonar.csv'
            , dataset_type  = 'tabular'
            , analysis_type = 'classification_binary'
            , label         = 'object'
            , label_classes = 2
            , features      = 60
            , samples       = 208
            , description   = 'Detecting either a rock "R" or mine "M". Each feature is a sensor reading.'
            , location      = 'local'
        ),
        dict(
            name            = 'houses.csv'
            , dataset_type  = 'tabular'
            , analysis_type = 'regression'
            , label         = 'price'
            , label_classes = 'N/A'
            , features      = 12
            , samples       = 506
            , description   = 'Predict the price of the house.'
            , location      = 'local'
        ),
        dict(
            name            = 'iris_noHeaders.csv' 
            , dataset_type  = 'tabular'
            , analysis_type = 'classification multi'
            , label         = 'species'
            , label_classes = 3
            , features      = 4
            , samples       = 150
            , description   = 'For testing; no column names.'
            , location      = 'local'
        ),
        dict(
            name            = 'iris_10x.tsv'
            , dataset_type  = 'tabular'
            , analysis_type = 'classification multi'
            , label         = 'species'
            , label_classes = 3
            , features      = 4
            , samples       = 1500
            , description   = 'For testing; duplicated 10x so cross-folds represent population.'
            , location      = 'local'
        ),
        dict(
            name            = 'brain_tumor.csv'
            , dataset_type  = 'image'
            , analysis_type = 'classification_binary'
            , label         = 'status'
            , label_classes = 2
            , features      = '1 color x 160 tall x 120 wide'
            , samples       = 80
            , description   = 'csv acts as label and manifest of image urls.'
            , location      = 'remote'
        ),
        dict(
            name            = 'galaxies.tsv'
            , dataset_type  = 'image'
            , analysis_type = 'classification_binary'
            , label         = 'morphology'
            , label_classes = 2
            , features      = '3 colors x 240 tall x 300 wide'
            , samples       = 40
            , description   = 'tsv acts as label and manifest of image urls.'
            , location      = 'remote'
        ),
        dict(
            name            = 'spam.csv'
            , dataset_type  = 'text'
            , analysis_type = 'classification_binary'
            , label         = 'v1'
            , label_classes = 2
            , features      = 'text data'
            , samples       = 5572
            , description   = 'collection of spam/ ham (not spam) messages'
            , location      = 'local'
        ),
        dict(
            name            = 'epilepsy.parquet'
            , dataset_type  = 'sequence'
            , analysis_type = 'classification_binary'
            , label         = 'seizure'
            , label_classes = 2
            , features      = '1 x 178 readings'
            , samples       = 1000
            , description   = "<https://archive.ics.uci.edu/ml/datasets/Epileptic+Seizure+Recognition> Storing the data tall so that it compresses better.`label_df = df[['seizure']]; sensor_arr3D = df.drop(columns=['seizure']).to_numpy().reshape(1000,178,1)`"
            , location      = 'local'
        ),
        dict(
            name            = 'delhi_climate.parquet'
            , dataset_type  = 'sequence'
            , analysis_type = 'forecasting'
            , label         = 'N/A'
            , label_classes = 'N/A'
            , features      = '3'
            , samples       = 1575
            , description   = "<https://www.kaggle.com/sumanthvrao/daily-climate-time-series-data>. Both train and test (pruned last day from train). 'pressure' and 'wind' columns seem to have outliers. Converted 'date' column to 'day_of_year.'"
            , location      = 'local'
        ),
        dict(
            name            = 'liberty_moon.csv'
            , dataset_type  = 'image'
            , analysis_type = 'forecasting'
            , label         = 'N/A'
            , label_classes = 'N/A'
            , features      = '1 color x 50 tall x 60 wide'
            , samples       = 15
            , description   = 'moon glides from top left to bottom right'
            , location      = 'remote'
        ),
    ]

    formats_df  = [None, 'pandas', 'df' ,'dataframe', 'd', 'pd']
    formats_lst = ['list', 'lst', 'l']
    if (format in formats_df):
        pd.set_option('display.max_column',100)
        pd.set_option('display.max_colwidth', 500)
        df = pd.DataFrame.from_records(records)
        return df
    elif (format in formats_lst):
        return records
    else:
        msg = f"\nYikes - The format you provided <{format}> is not one of the following:{formats_df} or {formats_lst}\n"
        raise Exception(msg)


def get_path(name:str):
    """
    - pkg_resources is used to dynamically find where the files are located on the system
    - In setup.py, `include_package_data=True,#triggers MANIFEST.in which grafts /data`
    - Remote datasets locations are just hardcoded for now.
    """
    if (name == 'brain_tumor.csv'):
        # 2nd aiqc is the repo, not the module.
        full_path = "https://raw.githubusercontent.com/aiqc/aiqc/main/remote_datum/image/brain_tumor/brain_tumor.csv"
    elif (name == 'galaxies.tsv'):
        full_path = "https://raw.githubusercontent.com/aiqc/aiqc/main/remote_datum/image/galaxy_morphology/galaxies.tsv"
    elif (name == 'liberty_moon.csv'):
        full_path = "https://raw.githubusercontent.com/aiqc/aiqc/main/remote_datum/image/liberty_moon/liberty_moon.csv"
    else:
        short_path = f"data/{name}"
        full_path = resource_filename('aiqc', short_path)
    return full_path


def to_df(name:str):
    file_path = get_path(name)

    if (('.tsv' in name) or ('.csv' in name)):
        if ('.tsv' in name):
            separator = '\t'
        elif ('.csv' in name):
            separator = ','
        else:
            separator = None
        df = pd.read_csv(file_path, sep=separator)
    elif ('.parquet' in name):
        df = pd.read_parquet(file_path)
    return df


def get_remote_urls(manifest_name:'str'):
    # `df=to_df` looks weird but it's right.
    df          = to_df(name=manifest_name)
    remote_urls = df['url'].to_list()
    return remote_urls
