package meerkat.crypto.dkg.feldman;

import meerkat.comm.Channel;

import java.math.BigInteger;
import java.util.*;

/**
 * Created by Tzlil on 3/21/2016.
 */
public class DKGMaliciousUser<T> extends User<T> {

    private final Protocol<T> maliciousDkg;
    private final Set<Integer> falls;
    public DKGMaliciousUser(Protocol<T> dkg, Protocol<T> maliciousDKG, Channel channel, Set<Integer> falls) {
        super(dkg, channel);
        this.falls = falls;
        this.maliciousDkg = maliciousDKG;
        maliciousDKG.setParties(parties);
    }

    public static Set<Integer> selectFallsRandomly(Set<Integer> ids, Random random){
        Set<Integer> falls = new HashSet<Integer>();
        ArrayList<Integer> idsList = new ArrayList<Integer>();
        for (int id : ids){
            idsList.add(id);
        }
        int fallsSize = random.nextInt(idsList.size()) + 1;// 1 - (n-1)
        while (falls.size() < fallsSize){
            falls.add(idsList.remove(random.nextInt(idsList.size())));
        }
        return falls;
    }

    public static <T> Protocol<T> generateMaliciousDKG(Protocol<T> dkg,Channel channel,Random random){
        BigInteger q = dkg.getQ();
        BigInteger zi = new BigInteger(q.bitLength(), random).mod(q);
        Protocol<T> malicious = new Protocol<T>(dkg.getT(),dkg.getN(),zi,random,dkg.getQ()
                ,dkg.getGenerator(),dkg.getGroup(),dkg.getId(),dkg.getEncoder());
        malicious.setChannel(channel);
        return malicious;
    }

    @Override
    public void stage1() {
        dkg.broadcastCommitments();
        sendSecrets(); //insteadof crypto.sendSecrets(channel);
    }

    @Override
    public void stage3() {
        maliciousDkg.answerAllComplainingPlayers();
    }

    @Override
    public void stage4(){
        // do nothing
    }

    private void sendSecrets(){
        for (int j = 1; j <= n ; j++){
            if(j != id){
                if(falls.contains(j)){
                    maliciousDkg.sendSecret(j);
                }else {
                    dkg.sendSecret(j);
                }
            }
        }
    }


}
