/*
 * 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.cryptolib.proofs.service;

import java.math.BigInteger;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.api.proofs.ProofsServiceAPI;
import com.scytl.cryptolib.commons.constants.Constants;
import com.scytl.cryptolib.commons.utils.validations.Validate;
import com.scytl.cryptolib.mathematical.groups.MathematicalGroup;
import com.scytl.cryptolib.mathematical.groups.impl.ZpGroupElement;
import com.scytl.cryptolib.proofs.cryptoapi.ProofPreComputerAPI;
import com.scytl.cryptolib.proofs.cryptoapi.ProofProverAPI;
import com.scytl.cryptolib.proofs.cryptoapi.ProofVerifierAPI;
import com.scytl.cryptolib.proofs.maurer.configuration.MaurerProofPolicyFromProperties;
import com.scytl.cryptolib.proofs.maurer.factory.MaurerUnifiedProofFactory;

/**
 * Implementation of the {@link ProofsService}.
 */
public final class ProofsService implements ProofsServiceAPI {

    private final MaurerUnifiedProofFactory<BigInteger, ZpGroupElement> _factory;

    /**
     * Default Constructor that uses a default path location.
     * 
     * @throws GeneralCryptoLibException
     *             if the default properties are invalid.
     */
    public ProofsService() throws GeneralCryptoLibException {

        this(Constants.CRYPTOLIB_POLICY_PROPERTIES_FILE_PATH);
    }

    /**
     * Constructor which initializes its state using the properties file located
     * at the specified path.
     * 
     * @param path
     *            the path of the properties file to be used to configure the
     *            service.
     * @throws GeneralCryptoLibException
     *             if the path is invalid or the properties are invalid.
     */
    public ProofsService(final String path)
            throws GeneralCryptoLibException {

        Validate.notNullOrBlank(path, "Properties file path");

        _factory =
            new MaurerUnifiedProofFactory<>(
                new MaurerProofPolicyFromProperties(path));
    }

    @Override
    public ProofProverAPI createProofProverAPI(
            final MathematicalGroup<?> group)
            throws GeneralCryptoLibException {

        Validate.notNull(group, "Zp subgroup");

        return _factory.createProofCreationAPI(group);
    }

    @Override
    public ProofVerifierAPI createProofVerifierAPI(
            final MathematicalGroup<?> group)
            throws GeneralCryptoLibException {

        Validate.notNull(group, "Zp subgroup");

        return _factory.createProofVerificationAPI(group);
    }

    @Override
    public ProofPreComputerAPI createProofPreComputerAPI(
            final MathematicalGroup<?> group)
            throws GeneralCryptoLibException {

        Validate.notNull(group, "Zp subgroup");

        return _factory.createProofPreComputationAPI(group);
    }
}
