"""
A config file drawn from another project that can be used as a testing palette here
"""
from yacs.config import CfgNode


class ConfigurationNode(CfgNode):
    """
    Same as CfgNode but with a hashing ability added for caching!
    """
    def __hash__(self):
        return self.__str__().__hash__()


# YACS overwrite these settings using YAML
__C = ConfigurationNode()

__C.MODEL_HAS_CHECKPOINTS = True

# The description for the experiment that is being done
__C.DESCRIPTION = 'no description!'

__C.DATASET = ConfigurationNode()

# Setup dataset settings
__C.DATASET.PATH_DATA_RAW = ConfigurationNode()
__C.DATASET.PATH_DATA_RAW.COMBO = '/path/not/specified/'
__C.DATASET.PATH_DATA_RAW.INFO = '/path/not/specified/'

#
__C.DATASET.COMBO_TABLE_NAME = 'ALMANAC2017.csv'
__C.DATASET.HAS_STUDY_SOURCES = False
__C.DATASET.STUDY_SOURCES = ['ALMANAC']
__C.DATASET.USE_EXTERNAL_INDICES_DIR = False
__C.DATASET.EXTERNAL_INDICES_DIR = '/path/not/specified/'
__C.DATASET.USE_EXTERNAL_INDICES = False
__C.DATASET.EXTERNAL_INDICES = []
__C.DATASET.RESPONSE_UPPER_BOUND = 500
__C.DATASET.RESPONSE_LOWER_BOUND = -500
__C.DATASET.USE_FOCUS_DRUG_LIST = False
__C.DATASET.FOCUS_DRUG_LIST = []
__C.DATASET.USE_FOCUS_CELL_LIST = False
__C.DATASET.FOCUS_CELL_LIST = []
__C.DATASET.USE_SCREENING_SAMPLE_RATIO = False
__C.DATASET.SCREENING_SAMPLE_RATIO = 1.0
__C.DATASET.USE_SCREENING_SAMPLE_COUNT = False
__C.DATASET.SCREENING_SAMPLE_COUNT = 4
__C.DATASET.CONSIDER_ONLY_MONOTHERAPIES = False

# Setup dataset drug setting
__C.DATASET.DRUG = ConfigurationNode()
__C.DATASET.DRUG.USE_SMILES = False
__C.DATASET.DRUG.GUIDE = 'not specified!'
__C.DATASET.DRUG.ATOM_FEATURES = 78
__C.DATASET.DRUG.USE_DRUG_EMBEDDINGS = True
__C.DATASET.DRUG.DETAIL_LEVEL = 1
__C.DATASET.DRUG.INCLUDE_MACCS = False
# Setup dataset cell setting
__C.DATASET.CELL = ConfigurationNode()
__C.DATASET.CELL.USE_EXPRESSION = True
__C.DATASET.CELL.EXPRESSION_SOURCE = 'ccle'
__C.DATASET.CELL.USE_EXPRESSION_ENCODER = False
__C.DATASET.CELL.EXPRESSION_ENCODER_TYPE = 'generic'
__C.DATASET.CELL.USE_GENE = False
__C.DATASET.CELL.REPLACE_GENE_NAMES_WITH_IDS = False
__C.DATASET.CELL.INCLUDE_CODE = True
__C.DATASET.CELL.INCLUDE_CNV = True
__C.DATASET.CELL.INCLUDE_CRISPR = True
__C.DATASET.CELL.INCLUDE_PROTEOMICS = True
__C.DATASET.CELL.DETAIL_LEVEL = 'D1'
# Setup dataset concentration setting
__C.DATASET.CONCENTRATION = ConfigurationNode()
__C.DATASET.CONCENTRATION.USE_ENCODER = True
__C.DATASET.CONCENTRATION.ENCODER_TYPE = 'one-hot'

# Setup training and testing splits
__C.TRAIN_TEST_SPLIT = ConfigurationNode()
__C.TRAIN_TEST_SPLIT.SPLIT_DIR = '/path/not/specified/'
__C.TRAIN_TEST_SPLIT.FOLD_INDICES_FILENAME = 'name_not_specified.pkl'

###
# Solving method
# - DeepDDR
# - Random Forest
###
__C.SOLVING_METHOD = 'Random Forest'

##
# Random forest configs
__C.RANDOM_FOREST = ConfigurationNode()

## Random forest dataloader configs
__C.RANDOM_FOREST.DATA_LOADER = ConfigurationNode()
__C.RANDOM_FOREST.DATA_LOADER.USE_DRUG_EMBEDDING = True
__C.RANDOM_FOREST.DATA_LOADER.USE_CONC_EMBEDDING = True
__C.RANDOM_FOREST.DATA_LOADER.USE_CELL_EMBEDDING = True
__C.RANDOM_FOREST.DATA_LOADER.USE_EXPRESSION = True

## Random forest solver settings
__C.RANDOM_FOREST.MODEL = ConfigurationNode()
__C.RANDOM_FOREST.MODEL.N_ESTIMATOR = 100

__C.RANDOM_FOREST.SOLVER = ConfigurationNode()
__C.RANDOM_FOREST.SOLVER.BATCH_SIZE = 5000
__C.RANDOM_FOREST.SOLVER.NUM_OF_WORKERS = -1  # Set to maximum

##
# Deep DDRM method
__C.DEEP_DDR = ConfigurationNode()
__C.DEEP_DDR.MODEL = ConfigurationNode()
__C.DEEP_DDR.MODEL.TYPE = 'type not specified!'
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS = ConfigurationNode()
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DROPOUT = 0.0

# Setup drug embedder
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DRUG_EMBEDDER = ConfigurationNode()
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DRUG_EMBEDDER.TYPE = 'type not specified'
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DRUG_EMBEDDER.HYPER_PARAMETERS = ConfigurationNode()
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DRUG_EMBEDDER.HYPER_PARAMETERS.GNN_TYPE = 'GNN not specified!'
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DRUG_EMBEDDER.HYPER_PARAMETERS.IN_FEATURES = -1
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DRUG_EMBEDDER.HYPER_PARAMETERS.DROPOUT = 0.0
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DRUG_EMBEDDER.HYPER_PARAMETERS.D_LAYERS = (-1, -1)
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DRUG_EMBEDDER.HYPER_PARAMETERS.OUT_FEATURES = -1
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DRUG_EMBEDDER.HYPER_PARAMETERS.ACTIVATION = 'activation not specified!'
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DRUG_EMBEDDER.HYPER_PARAMETERS.N_HEADS = -1
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.DRUG_EMBEDDER.HYPER_PARAMETERS.POOLING_OUT_FEATURES = -1

# Setup cell embedder
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.CELL_EMBEDDER = ConfigurationNode()
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.CELL_EMBEDDER.TYPE = 'type not specified'
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.CELL_EMBEDDER.HYPER_PARAMETERS = ConfigurationNode()
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.CELL_EMBEDDER.HYPER_PARAMETERS.DROPOUT = 0.0
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.CELL_EMBEDDER.HYPER_PARAMETERS.IN_FEATURES = -1
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.CELL_EMBEDDER.HYPER_PARAMETERS.OUT_FEATURES = -1
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.CELL_EMBEDDER.HYPER_PARAMETERS.H1 = -1
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.CELL_EMBEDDER.HYPER_PARAMETERS.H2 = -1

# Setup Fusion model
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.FUSION = ConfigurationNode()
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.FUSION.TYPE = 'type not specified'
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.FUSION.HYPER_PARAMETERS = ConfigurationNode()
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.FUSION.HYPER_PARAMETERS.DROPOUT = 0.0
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.FUSION.HYPER_PARAMETERS.CONC_IN_FEATURES = -1
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.FUSION.HYPER_PARAMETERS.HIDDEN_UNITS = (-1, -1)

# Setup integration model
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.INTEGRATION = ConfigurationNode()
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.INTEGRATION.TYPE = 'type not specified'
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.INTEGRATION.HYPER_PARAMETERS = ConfigurationNode()
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.INTEGRATION.HYPER_PARAMETERS.MAX_DRUG_COUNT = -1
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.INTEGRATION.HYPER_PARAMETERS.N_HEADS = -1
__C.DEEP_DDR.MODEL.HYPER_PARAMETERS.INTEGRATION.HYPER_PARAMETERS.H = -1

# The solver parameters
__C.DEEP_DDR.DATA_LOADER = ConfigurationNode()
__C.DEEP_DDR.DATA_LOADER.BATCH_SIZE = -1

__C.DEEP_DDR.SOLVER = ConfigurationNode()
__C.DEEP_DDR.SOLVER.USE_PRETRAINED_WEIGHTS = False
__C.DEEP_DDR.SOLVER.WEIGHT_INITIALIZATION_DIR = '/path/not/specified/'
__C.DEEP_DDR.SOLVER.N_EPOCHS = -1
__C.DEEP_DDR.SOLVER.DEVICE = 'device not specified!'
__C.DEEP_DDR.SOLVER.LOSS = 'loss not specified!'
__C.DEEP_DDR.SOLVER.OPTIMIZER = ConfigurationNode()
__C.DEEP_DDR.SOLVER.OPTIMIZER.TYPE = 'device not specified!'
__C.DEEP_DDR.SOLVER.OPTIMIZER.LR = 0.0

__C.OUTPUT = ConfigurationNode()
__C.OUTPUT.FILES_DIR = ['/path/not/specified1/', '/path/not/specified2/']
__C.OUTPUT.DESCRIPTIONS = ['description not specified1', 'description not specified2']


def get_cfg_defaults():
    """
    Get a yacs CfgNode object with default values
    """
    # Return a clone so that the defaults will not be altered
    # It will be subsequently overwritten with local YAML.
    return __C.clone()
