/*
 * 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.utils;

import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
import java.security.Security;

import org.apache.commons.io.IOUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.BeforeClass;
import org.junit.Test;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.api.primitives.PrimitivesServiceAPI;
import com.scytl.cryptolib.elgamal.bean.ElGamalPublicKey;
import com.scytl.cryptolib.primitives.primes.utils.PemUtils;
import com.scytl.cryptolib.primitives.service.PrimitivesService;

public class FingerprintGeneratorTest {

    private static PrimitivesServiceAPI _primitiveService;

    private static String RSA_PUBLIC_KEY_PATH = "/pem/rsaPublicKey.pem";

    private static final Charset CHAR_SET = StandardCharsets.UTF_8;

    private static FingerprintGenerator _target;

    @BeforeClass
    public static void setUp() throws GeneralCryptoLibException {

        Security.addProvider(new BouncyCastleProvider());

        _primitiveService = new PrimitivesService();

        _target = new FingerprintGenerator(_primitiveService);
    }

    @Test
    public void generate_a_fingerprint_for_a_RSA_public_key() throws IOException, GeneralCryptoLibException {

        PublicKey publicKey = readPublicKeyFromFile();

        String generatedFingerprint = _target.generate(publicKey);

        String expectedFingerprint = "T6eb+A48SzGLtVKOsW7xg5RBZyrXKnf3/lxP1GQt3So=";

        String errorMsg = "the generated fingerprint does not match the expected value";
        assertEquals(errorMsg, expectedFingerprint, generatedFingerprint);
    }

    @Test
    public void generate_a_fingerprint_for_an_ElGamal_public_key() throws IOException, GeneralCryptoLibException {

        String publicKeyAsJsonString_p2048_q256 =
            "{\"publicKey\":{\"zpSubgroup\":{\"p\":\"AONCJc0fvKlS+opYUNfGHZmKH42s9+Q2aMO/gbeWFr7cN00ehns9ppvJG2sXsztcabbdM3NGppxEC63kLS5yVh8WjY2JlrqNrFvB9t88QxX/ZkPfZjF8BmisAj1goapM0Qp0cHq65+tYUioVJkTgrlAexfMha6MblF1ujajNM4X1ESLGKrGSRqsWgdgKPRvwMtQXVKOXR179X0AKBJdWnCVCAlYExmHU+uNvvjhnKLGI2o5mRURKQQndOcjbsZfqdHc1JKIojhUcB4Dgh0DAOmGYxzPUzd5310SfKKYNwdCVjywPbXgHxBJRyi7As1THx99xSj31lJWsIp+S8Wm6is0=\",\"q\":\"AKDKPui2I7Pmk5amX6qgDiTyO59txsjFbI1EQk85IT7p\",\"g\":\"HlWC/C0smvRuu64RGlbCOQVEEKMVpDPX42DndP5ZSsDOQfKCdm57a8+HcliBhdhshAN4t0N8I2A3p3ej4Yc3rukNUdIMEoAOzJYTkFGkCFso90c+Hm8bggJE/OlL5jTY7NkFtRk6CVpue/MRgT4sSr/sCKu0zuJ7kgDOBhyT8V4V6/dxATWI+iClfI70m8GpZw9Bk5mHSypJ0pYYou/w+CqNzp0V6VtqndjKzQFDdl3T4T4gead1neX9icT7j2VM0LfO9Pb3lcCOQWOpuuy0zKxMX3qX5C+gVbc2W/QodgjHc2/K2kb9Zp/ndYP6g8x30Q39pZ5bYZvpKAmeJ/yT\"},\"elements\":[\"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\"]}}";
        ElGamalPublicKey publicKey = ElGamalPublicKey.fromJson(publicKeyAsJsonString_p2048_q256);

        String generatedFingerprint = _target.generate(publicKey);

        String expectedFingerprint = "aJ3/kqZtNJCiJUqvQplOYxqy2j9IuD87U107qTtEx1s=";

        String errorMsg = "the generated fingerprint does not match the expected value";
        assertEquals(errorMsg, expectedFingerprint, generatedFingerprint);
    }

    private PublicKey readPublicKeyFromFile() throws IOException, GeneralCryptoLibException {

        InputStream inStream = getClass().getResourceAsStream(RSA_PUBLIC_KEY_PATH);

        String pemStrIn = IOUtils.toString(inStream, CHAR_SET);

        PublicKey key = PemUtils.publicKeyFromPem(pemStrIn);

        return key;
    }

}
