#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import logging
import os
import random
from datetime import datetime

import numpy as np
import torch


def make_model_dir(config: dict) -> str:
    """
    Create a directory to contain various files for the current experiment.

    Args:
        config: a dictionary with the experiment settings

    Returns: string (name of the directory)

    """

    # Need to have only one directory for all experiments;
    # if it does not exist already, it will be created
    all_experiments_dir = os.path.abspath(config["experiments_dir"])

    # Create a simple unique name for the experiment.
    # This name consists of model type, timestamp and a random seed value.
    # First, generate the string denoting the model type to be trained.
    # Model types correspond to non-qualified names of the python files with the code for the model.
    # For example, if the code for our model is stored in "binlin/model/model_MLP.py",
    # then model type is "model_MLP".

    model_type = config['model-module'].split('.')[-1]
    timestamp = '{:%Y-%b-%d_%H:%M:%S}'.format(datetime.now())
    seed_val = config['random_seed']
    model_name = '%s_%s_seed-%d' % (model_type, timestamp, int(seed_val))

    # Specify the unique name for this experiment
    # by combining the 'experiment dir' and a unique model name
    model_dirname = os.path.join(all_experiments_dir, model_name)

    # create the experiment directory, if it does not exist
    if not os.path.exists(model_dirname):
        os.makedirs(model_dirname)

    return model_dirname


def fix_seed(seed:int):
    """
    Fix random seed value.
    Trying to do it for every random seed generator used in the project.

    Args:
        seed: an integer specifying the value of the random seed.

    Returns:

    """
    logging.debug("Fixing random seed (Random, Numpy, PyTorch, CUDA): %d" % seed)
    np.random.seed(seed)
    random.seed(seed)
    torch.manual_seed(seed)
    if torch.cuda.is_available():
        torch.cuda.manual_seed(seed)
