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

import static com.scytl.products.ov.commons.util.MathUtils.isqrt;

import java.io.IOException;
import java.math.BigInteger;
import java.util.List;
import java.util.Properties;

import com.scytl.products.ov.validation.ValidationEngineException;

/**
 * A utility class in charge of write a csv with the encrypted values.
 */
public class InputBallotsWriter {

	private static final int SINGLE_CHAR_SIZE_IF_ENCODED = 3;
	private static String charset;
	private static String separator;
	private static String dictionary;
	
	static {
        Properties props = new Properties();
        try {
			props.load(InputBallotsWriter.class.getResourceAsStream("/allowedCharacters.properties"));
		} catch (IOException e) {
			throw new ValidationEngineException("Error trying to load allowedCharacters.properties file.", e);
		}
        charset = props.getProperty("charset");
        separator = props.getProperty("separator").substring(0, 1);
        dictionary = charset.concat(separator);
	}

	/**
     * Non-public constructor
     */
	private InputBallotsWriter() {
    }
	
    public static void addWriteIns(List<String> values, List<BigInteger> writeIns, BigInteger p) {
		for (BigInteger bigInteger : writeIns) {
			String trimmedOriginal = isqrt(bigInteger.mod(p)).toString();
            int necessaryLeftPadding = 3-(trimmedOriginal.length() % 3);
            if(necessaryLeftPadding == 3){
            	necessaryLeftPadding = 0;
            }
            StringBuilder sb = new StringBuilder(trimmedOriginal.length() + necessaryLeftPadding);
            for (int i =0; i<necessaryLeftPadding ; i++){
                sb.append("0");
            }
            String original = sb.append(trimmedOriginal).toString();
            String decoded = decode(original);
            String[] split = decoded.split(separator);
            for (String string : split) {
				values.add(string);
			}
		}
	}
	
	private  static String decode(String toBeDecoded) {
		int length = toBeDecoded.length();
		StringBuilder sb = new StringBuilder(length / SINGLE_CHAR_SIZE_IF_ENCODED);
		for (int i = 0; i < length; i = i + SINGLE_CHAR_SIZE_IF_ENCODED){
			String substring = toBeDecoded.substring(i, i + SINGLE_CHAR_SIZE_IF_ENCODED);
			int intValue = Integer.parseInt(substring);
			char character = dictionary.charAt(intValue-1);
			sb.append(character);
		}
		return sb.toString();
	}
}
