/*
 * 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.ei.services.domain.model.rule;

import java.math.BigInteger;
import java.util.regex.PatternSyntaxException;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.scytl.products.ov.commons.beans.domain.model.vote.Vote;
import com.scytl.products.ov.commons.crypto.Constants;
import com.scytl.products.ov.commons.crypto.Utils;
import com.scytl.products.ov.commons.domain.model.rule.AbstractRule;
import com.scytl.products.ov.commons.validation.ValidationError;
import com.scytl.products.ov.commons.beans.validation.ValidationErrorType;

/**
 * Validate if the encrypted voting options are two big integers.
 */
public class EncryptedOptionsRule implements AbstractRule<Vote> {

	private static final Logger LOG = LoggerFactory.getLogger("std");

    /**
     * @see com.scytl.products.ov.commons.domain.model.rule.AbstractRule#execute(java.lang.Object)
     */
    @Override
    public ValidationError execute(Vote vote) {
        ValidationError result = new ValidationError();
        if (vote.getEncryptedOptions() != null) {
            try {
                String[] splitedEncryptedOptions =
                    vote.getEncryptedOptions().split(Constants.SEPARATOR_ENCRYPTED_OPTIONS);
                if (splitedEncryptedOptions.length == 2) {
                    new BigInteger(Utils.getC0FromEncryptedOptions(vote.getEncryptedOptions()));
                    new BigInteger(Utils.getC1FromEncryptedOptions(vote.getEncryptedOptions()));
                    result.setValidationErrorType(ValidationErrorType.SUCCESS);
                } else {
                    result.setValidationErrorType(ValidationErrorType.FAILED);
                    result.setErrorArgs(new String[] {"Incorrect number of encrypted options" });
                }
            } catch (PatternSyntaxException | NumberFormatException e) {
                LOG.error("Error validating encrypted options: ", e);
                result.setValidationErrorType(ValidationErrorType.FAILED);
                result.setErrorArgs(new String[] {"Error validating encrypted options "
                    + ExceptionUtils.getRootCauseMessage(e) });
            }
        } else {
            result.setValidationErrorType(ValidationErrorType.FAILED);
            result.setErrorArgs(new String[] {"There are not encrypted options in the vote" });
        }
        return result;
    }

    /**
     * @see com.scytl.products.ov.commons.domain.model.rule.AbstractRule#getName()
     */
    @Override
    public String getName() {
        return RuleNames.VOTE_OPTIONS_BIG_INTEGERS.getText();
    }

}
