package org.jivesoftware.smackx.ikey;

import org.bouncycastle.util.encoders.Base64;
import org.jivesoftware.smackx.ikey.element.IkeyElement;
import org.jivesoftware.smackx.ikey.mechanism.IkeySignatureVerificationMechanism;
import org.jivesoftware.smackx.ikey.util.canonicalization.ElementCanonicalizer;
import org.jxmpp.jid.EntityBareJid;

import java.io.IOException;

public class IkeySignatureVerifier {

    private final IkeySignatureVerificationMechanism signatureVerificationMechanism;
    private final ElementCanonicalizer elementCanonicalizer;

    public IkeySignatureVerifier(IkeySignatureVerificationMechanism signatureVerificationMechanism, ElementCanonicalizer elementCanonicalizer) {
        this.signatureVerificationMechanism = signatureVerificationMechanism;
        this.elementCanonicalizer = elementCanonicalizer;
    }

    public boolean verify(IkeyElement element, EntityBareJid owner)
            throws IOException {
        throwIfMismatchingMechanism(element);
        throwIfMismatchingOwnerJid(element, owner);

        byte[] canonicalizedXml = elementCanonicalizer.canonicalize(element.getSubordinates());
        byte[] signature = Base64.decode(element.getProof().getBase64Signature());

        return signatureVerificationMechanism.isSignatureValid(canonicalizedXml, signature);
    }

    private static void throwIfMismatchingOwnerJid(IkeyElement element, EntityBareJid owner) {
        if (!element.getSubordinates().getJid().equals(owner)) {
            throw new IllegalArgumentException("Provided ikey element does not contain jid of " + owner);
        }
    }

    private void throwIfMismatchingMechanism(IkeyElement element) {
        if (element.getType() != signatureVerificationMechanism.getType()) {
            throw new IllegalArgumentException("Element was created using mechanism " + element.getType() +
                    " but this is a verifier for " + signatureVerificationMechanism.getType() + " ikey elements.");
        }
    }
}
