from androidcrypto.analysis.preparation.feature_scaling import feature_scaling_based_on_config
from typing import Optional, Dict, Tuple, Union
import tempfile
from pathlib import Path

import pandas as pd

from androidcrypto.analysis.preparation.config import PreparationConfig
from androidcrypto.analysis.preparation.cleaning import clean_based_on_config
from androidcrypto.analysis.preparation.records_selection import records_selection_based_on_config
from androidcrypto.analysis.preparation.feature_engineering import feature_engineering_based_on_config
from androidcrypto.analysis.preparation.feature_selection import feature_selection_based_on_config
from androidcrypto.analysis.preparation.utils import download_file
from androidcrypto.constants import DATASET_MENDELEY_URL


def prepare_based_on_config(
    config: PreparationConfig
    ) -> Optional[Union[
        Dict[str, Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame, pd.DataFrame]], # feature selectiobn/engineering
        Dict[str, Tuple[pd.DataFrame, pd.DataFrame]], # records selection
        pd.DataFrame # cleaning
        ]]:

    # cleaning
    df = None # initialize to None and in case of cleaning set it to result
    if config.cleaning:
        df = clean_based_on_config(config.cleaning)

    if config.feature_engineering:
        df = feature_engineering_based_on_config(df, config.feature_engineering)

    # records selection
    task_dfs = None # to be dictionary with task as key and tuple of train/test feature/label
    if config.records_selection:
        task_dfs = records_selection_based_on_config(df, config.records_selection)
    
    if config.feature_scaling:
        task_dfs = feature_scaling_based_on_config(task_dfs, config.feature_scaling)

    # feature selection
    if config.feature_selection:
        task_dfs = feature_selection_based_on_config(task_dfs, config.feature_selection)
    
    if task_dfs is not None:
        return task_dfs
    return df


def get_dataset_from_web() -> pd.DataFrame:
    with tempfile.TemporaryDirectory() as tmp_dir:
        dset_path = Path(tmp_dir) / 'latest_dataset.csv'
        download_file(DATASET_MENDELEY_URL, dset_path)
        return pd.read_csv(dset_path)

from androidcrypto.analysis.preparation.feature_scaling import feature_scaling_based_on_config
from typing import Optional, Dict, Tuple, Union
import tempfile
from pathlib import Path

import pandas as pd

from androidcrypto.analysis.preparation.config import PreparationConfig
from androidcrypto.analysis.preparation.cleaning import clean_based_on_config
from androidcrypto.analysis.preparation.records_selection import records_selection_based_on_config
from androidcrypto.analysis.preparation.feature_engineering import feature_engineering_based_on_config
from androidcrypto.analysis.preparation.feature_selection import feature_selection_based_on_config
from androidcrypto.analysis.preparation.utils import download_file
from androidcrypto.constants import DATASET_MENDELEY_URL


def prepare_based_on_config(
    config: PreparationConfig
    ) -> Optional[Union[
        Dict[str, Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame, pd.DataFrame]], # feature selectiobn/engineering
        Dict[str, Tuple[pd.DataFrame, pd.DataFrame]], # records selection
        pd.DataFrame # cleaning
        ]]:

    # cleaning
    df = None # initialize to None and in case of cleaning set it to result
    if config.cleaning:
        df = clean_based_on_config(config.cleaning)

    if config.feature_engineering:
        df = feature_engineering_based_on_config(df, config.feature_engineering)

    # records selection
    task_dfs = None # to be dictionary with task as key and tuple of train/test feature/label
    if config.records_selection:
        task_dfs = records_selection_based_on_config(df, config.records_selection)
    
    if config.feature_scaling:
        task_dfs = feature_scaling_based_on_config(task_dfs, config.feature_scaling)

    # feature selection
    if config.feature_selection:
        task_dfs = feature_selection_based_on_config(task_dfs, config.feature_selection)
    
    if task_dfs is not None:
        return task_dfs
    return df


def get_dataset_from_web() -> pd.DataFrame:
    with tempfile.TemporaryDirectory() as tmp_dir:
        dset_path = Path(tmp_dir) / 'latest_dataset.csv'
        download_file(DATASET_MENDELEY_URL, dset_path)
        return pd.read_csv(dset_path)

# feature selectiobn/engineering # records selection # cleaning # cleaning # initialize to None and in case of cleaning set it to result # records selection # to be dictionary with task as key and tuple of train/test feature/label # feature selection