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

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.security.KeyPair;
import java.security.Security;
import java.util.LinkedHashMap;

import javax.json.Json;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import com.scytl.cryptolib.api.asymmetric.AsymmetricServiceAPI;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.asymmetric.service.AsymmetricService;
import com.scytl.products.ov.commons.sign.MetadataFileSigner;
import com.scytl.products.ov.commons.sign.SignatureMetadata;

public class MetaDataVerifierTest {



    private KeyPair keyPairForSigning;

    private AsymmetricServiceAPI asymmetricService;
    
    @BeforeClass
    public static void setUp() throws GeneralCryptoLibException {

        Security.addProvider(new BouncyCastleProvider());
        
    }

    @Before
    public void init() throws GeneralCryptoLibException {

        asymmetricService = new AsymmetricService();
        keyPairForSigning = asymmetricService.getKeyPairForSigning();

    }


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

        final Path tempFile = Files.createTempFile("result", "metadata.csv");
        LinkedHashMap<String, String> metadataMap = new LinkedHashMap<>();
        metadataMap.put("eeId", "eeid");
        MetadataFileSigner signer = new MetadataFileSigner(asymmetricService);
        SignatureMetadata signature;
        MetadataFileVerifier metadataFileVerifier = new MetadataFileVerifier(asymmetricService);
        try (InputStream encryptedBallotInputStream = ClassLoader.getSystemResourceAsStream("encryptedBallot.csv");
                OutputStream os = Files.newOutputStream(tempFile, StandardOpenOption.CREATE)) {
            signature = signer.createSignature(keyPairForSigning.getPrivate(), encryptedBallotInputStream, metadataMap);
            Json.createWriter(os).writeObject(signature.toJsonObject());
        }

        try (InputStream metadataInputStream = Files.newInputStream(tempFile);
                InputStream encryptedBallotInputStream = ClassLoader.getSystemResourceAsStream("encryptedBallot.csv")) {
            final boolean verify = metadataFileVerifier.verifySignature(keyPairForSigning.getPublic(),
                metadataInputStream, encryptedBallotInputStream);
            assertTrue(verify);
        }

    }


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

        final Path tempFile = Files.createTempFile("result", "metadata.csv");
        LinkedHashMap<String, String> metadataMap = new LinkedHashMap<>();
        metadataMap.put("eeId", "eeid");
        MetadataFileSigner signer = new MetadataFileSigner(asymmetricService);
        SignatureMetadata signature;
        MetadataFileVerifier metadataFileVerifier = new MetadataFileVerifier(asymmetricService);
        try (InputStream encryptedBallotInputStream = ClassLoader.getSystemResourceAsStream("encryptedBallot.csv");
             OutputStream os = Files.newOutputStream(tempFile, StandardOpenOption.CREATE)) {
            signature = signer.createSignature(keyPairForSigning.getPrivate(), encryptedBallotInputStream, metadataMap);
            Json.createWriter(os).writeObject(signature.toJsonObject());
        }

        try (InputStream metadataInputStream = Files.newInputStream(tempFile);
             InputStream encryptedBallotInputStream = ClassLoader.getSystemResourceAsStream("encryptedBallotWrong.csv")) {
            final boolean verify = metadataFileVerifier.verifySignature(keyPairForSigning.getPublic(),
                    metadataInputStream, encryptedBallotInputStream);
            assertFalse(verify);
        }
    }

}
