package org.jivesoftware.smackx.ikey_ox;

import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.util.io.Streams;
import org.jivesoftware.smackx.ikey.mechanism.IkeySignatureCreationMechanism;
import org.jivesoftware.smackx.ikey.mechanism.IkeyType;
import org.pgpainless.PGPainless;
import org.pgpainless.encryption_signing.EncryptionStream;
import org.pgpainless.key.protection.SecretKeyRingProtector;

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

public class OxIkeySignatureCreationMechanism implements IkeySignatureCreationMechanism {

    private final PGPSecretKeyRing ourIdentityKey;
    private final SecretKeyRingProtector secretKeyRingProtector;

    public OxIkeySignatureCreationMechanism(PGPSecretKeyRing ourIdentityKey,
                                            SecretKeyRingProtector secretKeyRingProtector) {
        this.ourIdentityKey = ourIdentityKey;
        this.secretKeyRingProtector = secretKeyRingProtector;
    }

    @Override
    public byte[] createSignature(byte[] data) throws IOException {
        try {
            ByteArrayOutputStream dummyOutputStream = new ByteArrayOutputStream();
            EncryptionStream encryptionStream = PGPainless.createEncryptor()
                    .onOutputStream(dummyOutputStream)
                    .doNotEncrypt()
                    .createDetachedSignature()
                    .signWith(secretKeyRingProtector, ourIdentityKey)
                    .noArmor();
            ByteArrayInputStream dataIn = new ByteArrayInputStream(data);
            Streams.pipeAll(dataIn, encryptionStream);

            encryptionStream.close();
            dataIn.close();

            PGPSignature signature = encryptionStream.getResult().getSignatures()
                    .iterator().next();
            return signature.getEncoded();
        } catch (PGPException e) {
            throw new IOException(e);
        }
    }

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