/*
 * 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.beans.domain.model.messaging;

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

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.primitives.primes.utils.PemUtils;

/**
 * Scytl's CryptoLib-based vote set signature.
 */
public class CryptolibPayloadSignature implements PayloadSignature {

    private static final long serialVersionUID = -8556532035098303477L;

    private final byte[] signatureContents;

    @JsonSerialize(contentUsing = PemSerializer.class)
    @JsonDeserialize(contentUsing = PemDeserializer.class)
    private final X509Certificate[] certificateChain;

    public static class PemSerializer extends JsonSerializer<X509Certificate> {
        @Override
        public void serialize(X509Certificate value, JsonGenerator gen, SerializerProvider serializers)
                throws IOException, JsonProcessingException {
            try {
                gen.writeString(PemUtils.certificateToPem(value));
            } catch (GeneralCryptoLibException e) {
                throw new IOException(e);
            }
        }
    }

    public static class PemDeserializer extends JsonDeserializer<X509Certificate> {
        @Override
        public X509Certificate deserialize(JsonParser p, DeserializationContext ctxt)
                throws IOException, JsonProcessingException {
            try {
                return (X509Certificate) PemUtils.certificateFromPem(p.readValueAs(String.class));
            } catch (GeneralCryptoLibException e) {
                throw new IOException(e);
            }
        }
    }

    /**
     * Creates the representation of a Cryptolib-based signature.
     *
     * @param signatureContents
     *            the byte stream containing the signature
     * @param certificateChain
     *            the certificate chain to be used when validating the signature
     */
    @JsonCreator
    public CryptolibPayloadSignature(@JsonProperty("signatureContents") byte[] signatureContents,
            @JsonProperty("certificateChain") X509Certificate[] certificateChain) {
        this.signatureContents = signatureContents;
        this.certificateChain = certificateChain;
    }

    @Override
    public X509Certificate[] getCertificateChain() {
        return certificateChain;
    }

    /**
     * @return the byte array representing the signature
     */
    @Override
    public byte[] getSignatureContents() {
        return signatureContents;
    }
}
