# -*- coding: utf-8 -*-
"""Auxiliary functions that support for system."""
import time
import torch
from datetime import datetime

def str2time(string, pattern):
    """convert the string to the datetime."""
    return datetime.strptime(string, pattern)


def determine_model_info(args):
    if 'resnet' in args.arch:
        return args.arch
    elif 'densenet' in args.arch:
        return '{}{}-{}{}'.format(
            args.arch, args.densenet_growth_rate,
            'BC-' if args.densenet_bc_mode else '',
            args.densenet_compression
        )
    elif 'wideresnet' in args.arch:
        return '{}-{}'.format(
            args.arch, args.wideresnet_widen_factor
        )


def info2path(args):
    info = '{}_{}_'.format(int(time.time()), determine_model_info(args))
    info += 'lr-{}_momentum-{}_epochs-{}_batchsize-{}_droprate-{}_'.format(
        args.lr,
        args.momentum,
        args.num_epochs,
        args.batch_size,
        args.drop_rate)
    info += 'lars-{}-{}_'.format(args.lr_lars_mode, args.lr_lars_eta) \
        if args.lr_lars else ''

    if args.num_format != 'fp32':
        info += '{}-{}_mant_bits-{}_tilesize-{}'.format(
            args.num_format, args.rounding_mode,
            args.mant_bits, args.bfp_tile_size)
        return info
    else:
        return info


def zeros_like(x):
    assert x.__class__.__name__.find('Variable') != -1 or \
        x.__class__.__name__.find('Tensor') != -1, \
        "Object is neither a Tensor nor a Variable"

    y = torch.zeros(x.size())
    y = y.to(x.device)

    if x.__class__.__name__ == 'Variable':
        return torch.autograd.Variable(y, requires_grad=x.requires_grad)
    elif x.__class__.__name__.find('Tensor') != -1:
        return y
