package org.jivesoftware.smackx.ikey_ox;

import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.util.io.Streams;
import org.jivesoftware.smackx.ikey.mechanism.IkeySignatureVerificationMechanism;
import org.jivesoftware.smackx.ikey.mechanism.IkeyType;
import org.pgpainless.PGPainless;
import org.pgpainless.decryption_verification.DecryptionStream;
import org.pgpainless.decryption_verification.OpenPgpMetadata;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collections;

public class OxIkeySignatureVerificationMechanism implements IkeySignatureVerificationMechanism {

    private PGPPublicKeyRing contactIdentityKey;

    public OxIkeySignatureVerificationMechanism(PGPPublicKeyRing contactIdentityKey) {
        this.contactIdentityKey = contactIdentityKey;
    }

    @Override
    public boolean isSignatureValid(byte[] data, byte[] signature) throws IOException {
        try {
            DecryptionStream decryptionInputStream = PGPainless.createDecryptor()
                    .onInputStream(new ByteArrayInputStream(data))
                    .doNotDecrypt()
                    .verifyDetachedSignature(new ByteArrayInputStream(signature))
                    .verifyWith(Collections.singleton(contactIdentityKey))
                    .ignoreMissingPublicKeys()
                    .build();
            ByteArrayOutputStream decryptionOutputStream = new ByteArrayOutputStream(data.length);
            Streams.pipeAll(decryptionInputStream, decryptionOutputStream);

            decryptionInputStream.close();
            decryptionOutputStream.close();

            OpenPgpMetadata metadata = decryptionInputStream.getResult();
            return !metadata.getVerifiedSignatures().isEmpty();
        } catch (PGPException e) {
            throw new IOException(e);
        }
    }

    @Override
    public IkeyType getType() {
        return IkeyType.OX;
    }

}
