import torch


def parse_optimizer(hparams, model):
    """
    Creates an optimizer for the given model using the argumentes specified in
    hparams.

    Arguments:
    -----------
    :param hparams: Hyperparameters dictionary
    :param model: An nn.Module object
    :return: a torch.optim object
    """
    # optimizer configuration
    optimizer = {
        "adadelta": torch.optim.Adadelta,
        "adagrad": torch.optim.Adagrad,
        "adam": torch.optim.Adam,
        "rmsprop": torch.optim.RMSprop,
        "adamax": torch.optim.Adamax,
        "rprop": torch.optim.Rprop,
        "sgd": torch.optim.SGD,
    }.get(hparams["optimizer"].lower(), None)
    assert optimizer is not None, "{} optimizer could not be found"

    # filter optimizer arguments
    optim_kwargs = dict()
    optim_key = hparams["optimizer"]
    for k, v in hparams.items():
        if "optimizer__" in k:
            attribute_tup = k.split("__")
            if optim_key == attribute_tup[1] or attribute_tup[1] == "global":
                optim_kwargs[attribute_tup[2]] = v
    optimizer = optimizer(model.parameters(), **optim_kwargs)
    return optimizer