package meerkat.util;

import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.protobuf.Crypto.*;

import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

/**
 * Created by Arbel Deutsch Peled on 05-Dec-15.
 * This class implements a comparison between BulletinBoardMessage instances that disregards:
 * 1. The entry number (since this can be different between database instances)
 * 2. The order of the signatures
 */
public class BulletinBoardMessageComparator implements Comparator<BulletinBoardMessage> {

    /**
     * Compare the messages
     * @param msg1
     * @param msg2
     * @return 0 if the messages are equivalent (see above) and -1 otherwise.
     */
    @Override
    public int compare(BulletinBoardMessage msg1, BulletinBoardMessage msg2) {



        // Compare Timestamps

        if (!msg1.getMsg().getTimestamp().equals(msg2.getMsg().getTimestamp())){
            return -1;
        }

        // Compare tags (enforce order)

        List<String> tags1 = msg1.getMsg().getTagList();
        Iterator<String> tags2 = msg2.getMsg().getTagList().iterator();

        for (String tag : tags1){
            if (!tags2.hasNext()) {
                return -1;
            }
            if (!tags2.next().equals(tag)){
                return -1;
            }
        }

        // Compare data

        if (msg1.getMsg().getDataTypeCase() != msg2.getMsg().getDataTypeCase()){
            return -1;
        }

        if (msg1.getMsg().getDataTypeCase() == UnsignedBulletinBoardMessage.DataTypeCase.DATA){
            if (!msg1.getMsg().getData().equals(msg2.getMsg().getData())){
                return -1;
            }
        } else if (msg1.getMsg().getDataTypeCase() == UnsignedBulletinBoardMessage.DataTypeCase.MSGID){
            if (!msg1.getMsg().getMsgId().equals(msg2.getMsg().getMsgId())){
                return -1;
            }
        }

        // Compare signatures (do not enforce order)

        List<Signature> sigs1 = msg1.getSigList();
        List<Signature> sigs2 = msg2.getSigList();

        if (sigs1.size() != sigs2.size()){
            return -1;
        }

        for (Signature sig : sigs1){
            if (!sigs2.contains(sig)) {
                return -1;
            }
        }

        return 0;
    }
}
