/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.commons.dto;

import static com.scytl.products.ov.commons.safestream.StreamSerializableUtil.*;

import java.io.IOException;
import java.security.cert.X509Certificate;

import org.msgpack.core.MessagePacker;
import org.msgpack.core.MessageUnpacker;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.elgamal.bean.ElGamalPublicKey;
import com.scytl.products.ov.commons.beans.domain.model.messaging.SafeStreamDeserializationException;
import com.scytl.products.ov.commons.beans.domain.model.messaging.StreamSerializable;
import com.scytl.products.ov.commons.beans.domain.model.messaging.StreamSerializableClassType;

public class CCPublicKey implements StreamSerializable {

    private ElGamalPublicKey publicKey;

    private KeyType keytype;

    private byte[] keySignature;

    private X509Certificate signerCertificate;

    private X509Certificate nodeCACertificate;

    public ElGamalPublicKey getPublicKey() {
        return publicKey;
    }

    public void setPublicKey(ElGamalPublicKey publicKey) {
        this.publicKey = publicKey;
    }

    public KeyType getKeytype() {
        return keytype;
    }

    public void setKeytype(KeyType keytype) {
        this.keytype = keytype;
    }

    public void setKeySignature(byte[] keySignature) {
        this.keySignature = keySignature;
    }

    public void setSignerCertificate(X509Certificate signerCertificate) {
        this.signerCertificate = signerCertificate;
    }

    public void setNodeCACertificate(X509Certificate nodeCACertificate) {
        this.nodeCACertificate = nodeCACertificate;
    }

    public byte[] getKeySignature() {
        return keySignature;
    }

    public X509Certificate getSignerCertificate() {
        return signerCertificate;
    }

    public X509Certificate getNodeCACertificate() {
        return nodeCACertificate;
    }

    @Override
    public void serialize(MessagePacker packer) throws IOException {

        try {
            storeElGamalPublicKeyValueWithNullCheck(packer, publicKey);
            packer.packString(keytype.toString());
            if (keySignature != null) {
                packer.packBinaryHeader(keySignature.length);
                packer.addPayload(keySignature);
            } else {
                packer.packNil();
            }
            storeCertificateValueWithNullCheck(packer, signerCertificate);
            storeCertificateValueWithNullCheck(packer, nodeCACertificate);
        } catch (GeneralCryptoLibException e) {
            throw new IOException(e);
        }

    }

    @Override
    public void deserialize(MessageUnpacker unpacker) throws SafeStreamDeserializationException {
        try {
            this.publicKey = retrieveElGamalPublicKeyValueWithNullCheck(unpacker);
            this.keytype = KeyType.valueOf(unpacker.unpackString());
            if (!unpacker.tryUnpackNil()) {
                int signatureLength = unpacker.unpackBinaryHeader();
                this.keySignature = unpacker.readPayload(signatureLength);
            } else {
                this.keySignature = null;
            }
            this.signerCertificate = retrieveCertificateValueWithNullCheck(unpacker);
            this.nodeCACertificate = retrieveCertificateValueWithNullCheck(unpacker);
        } catch (IOException | GeneralCryptoLibException e) {
            throw new SafeStreamDeserializationException(e);
        }
    }

    @Override
    public StreamSerializableClassType type() {
        return StreamSerializableClassType.CC_PUBLIC_KEY;
    }

}
