def build_attack(attack_name, device='cpu', args=None, mode='modification'):
    if (mode == 'modification'):
        if (attack_name == 'dice'):
            from grb.attack.modification import DICE
            attack = DICE(n_edge_mod=args.n_edge_mod, ratio_delete=0.6, device=device)
            return attack
        if (attack_name == 'fga'):
            from grb.attack.modification import FGA
            attack = FGA(n_edge_mod=args.n_edge_mod, device=device)
            return attack
        if (attack_name == 'flip'):
            from grb.attack.modification import FLIP
            attack = FLIP(n_edge_mod=args.n_edge_mod, flip_type=args.flip_type, mode='descend', device=device)
            return attack
        if (attack_name == 'rand'):
            from grb.attack.modification import RAND
            attack = RAND(n_edge_mod=args.n_edge_mod, device=device)
            return attack
        if (attack_name == 'nea'):
            from grb.attack.modification import NEA
            attack = NEA(n_edge_mod=args.n_edge_mod, device=device)
            return attack
        if (attack_name == 'stack'):
            from grb.attack.modification import STACK
            attack = STACK(n_edge_mod=args.n_edge_mod, device=device)
            return attack
        if (attack_name == 'pgd'):
            from grb.attack.modification import PGD
            attack = PGD(epsilon=args.epsilon, n_epoch=args.attack_epoch, n_node_mod=args.n_node_mod, n_edge_mod=args.n_edge_mod, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, device=device)
            return attack
        if (attack_name == 'prbcd'):
            from grb.attack.modification import PRBCD
            attack = PRBCD(epsilon=args.epsilon, n_epoch=args.attack_epoch, n_node_mod=args.n_node_mod, n_edge_mod=args.n_edge_mod, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, device=device)
            return attack
    elif (mode == 'injection'):
        if (attack_name == 'rand'):
            from grb.attack.injection import RAND
            attack = RAND(n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, device=device)
            return attack
        elif (attack_name == 'fgsm'):
            from grb.attack.injection import FGSM
            attack = FGSM(epsilon=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, device=device)
            return attack
        elif (attack_name == 'pgd'):
            from grb.attack.injection import PGD
            attack = PGD(epsilon=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, device=device)
            return attack
        elif (attack_name == 'speit'):
            from grb.attack.injection import SPEIT
            attack = SPEIT(lr=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, device=device)
            return attack
        elif (attack_name == 'tdgia'):
            from grb.attack.injection import TDGIA
            attack = TDGIA(lr=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, inject_mode='random', sequential_step=1.0, device=device)
            return attack
        elif (attack_name == 'tdgia_random'):
            from grb.attack.injection.tdgia import TDGIA
            attack = TDGIA(lr=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, inject_mode='random', device=device)
            return attack
        elif (attack_name == 'tdgia_uniform'):
            from grb.attack.injection import TDGIA
            attack = TDGIA(lr=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, inject_mode='uniform', sequential_step=1.0, device=device)
            return attack
    else:
        raise NotImplementedError
def build_attack(attack_name, device='cpu', args=None, mode='modification'):
    if (mode == 'modification'):
        if (attack_name == 'dice'):
            from grb.attack.modification import DICE
            attack = DICE(n_edge_mod=args.n_edge_mod, ratio_delete=0.6, device=device)
            return attack
        if (attack_name == 'fga'):
            from grb.attack.modification import FGA
            attack = FGA(n_edge_mod=args.n_edge_mod, device=device)
            return attack
        if (attack_name == 'flip'):
            from grb.attack.modification import FLIP
            attack = FLIP(n_edge_mod=args.n_edge_mod, flip_type=args.flip_type, mode='descend', device=device)
            return attack
        if (attack_name == 'rand'):
            from grb.attack.modification import RAND
            attack = RAND(n_edge_mod=args.n_edge_mod, device=device)
            return attack
        if (attack_name == 'nea'):
            from grb.attack.modification import NEA
            attack = NEA(n_edge_mod=args.n_edge_mod, device=device)
            return attack
        if (attack_name == 'stack'):
            from grb.attack.modification import STACK
            attack = STACK(n_edge_mod=args.n_edge_mod, device=device)
            return attack
        if (attack_name == 'pgd'):
            from grb.attack.modification import PGD
            attack = PGD(epsilon=args.epsilon, n_epoch=args.attack_epoch, n_node_mod=args.n_node_mod, n_edge_mod=args.n_edge_mod, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, device=device)
            return attack
        if (attack_name == 'prbcd'):
            from grb.attack.modification import PRBCD
            attack = PRBCD(epsilon=args.epsilon, n_epoch=args.attack_epoch, n_node_mod=args.n_node_mod, n_edge_mod=args.n_edge_mod, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, device=device)
            return attack
    elif (mode == 'injection'):
        if (attack_name == 'rand'):
            from grb.attack.injection import RAND
            attack = RAND(n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, device=device)
            return attack
        elif (attack_name == 'fgsm'):
            from grb.attack.injection import FGSM
            attack = FGSM(epsilon=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, device=device)
            return attack
        elif (attack_name == 'pgd'):
            from grb.attack.injection import PGD
            attack = PGD(epsilon=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, device=device)
            return attack
        elif (attack_name == 'speit'):
            from grb.attack.injection import SPEIT
            attack = SPEIT(lr=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, device=device)
            return attack
        elif (attack_name == 'tdgia'):
            from grb.attack.injection import TDGIA
            attack = TDGIA(lr=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, inject_mode='random', sequential_step=1.0, device=device)
            return attack
        elif (attack_name == 'tdgia_random'):
            from grb.attack.injection.tdgia import TDGIA
            attack = TDGIA(lr=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, inject_mode='random', device=device)
            return attack
        elif (attack_name == 'tdgia_uniform'):
            from grb.attack.injection import TDGIA
            attack = TDGIA(lr=args.lr, n_epoch=args.n_epoch, n_inject_max=args.n_inject_max, n_edge_max=args.n_edge_max, feat_lim_min=args.feat_lim_min, feat_lim_max=args.feat_lim_max, early_stop=args.early_stop, inject_mode='uniform', sequential_step=1.0, device=device)
            return attack
    else:
        raise NotImplementedError