from pathlib import Path
import os
import time
import logging
import yaml
from torch.utils.tensorboard import SummaryWriter


class Dict(dict):
    __setattr__ = dict.__setitem__
    __getattr__ = dict.__getitem__


def dict2object(_dict):
    if not isinstance(_dict, dict):
        return _dict
    inst = Dict()
    for key, val in _dict.items():
        inst[key] = dict2object(val)
    return inst

def merge_dict(config, _dict):
    if not isinstance(_dict, dict):
        return _dict
    for key, val in _dict.items():
        config[key] = None
        config[key] = merge_dict(config[key], val)

def merge_list(config, _list):
    keys = _list[::2]
    values = _list[1::2]
    for key, val in zip(keys, values):
        if key in config:
            config[key] = type(config[key])(val)
        else:
            config[key] = val


def create_logger(args):
    if 'cfg' in args.__dict__:
        with open(args.cfg) as f:
            cfg = yaml.load(f, Loader=yaml.FullLoader)
    else:
        cfg = Dict()
    cfg = dict2object(cfg)
    merge_dict(cfg, args.__dict__)
    if 'opts' in args:
        merge_dict(cfg, args.opts)
    path = Path(os.path.join(cfg.save_path, cfg.tag))
    log_dir = path / Path(cfg.log_dir)
    print('=> Creating {}'.format(log_dir))
    log_dir.mkdir(parents=True, exist_ok=True)
    cfg.writer = SummaryWriter(str(log_dir))

    log_file = log_dir / 'log.txt'
    head = '%(asctime)-15s %(message)s'
    logging.basicConfig(filename=str(log_file), format=head)
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    console = logging.StreamHandler()
    logging.getLogger('').addHandler(console)
    model_dir = path / Path(cfg.model_dir)
    model_dir.mkdir(parents=True, exist_ok=True)
    cfg.model_dir = str(model_dir)
    return cfg, logger
        


