package io.codearte.jfairy.producer.person.locale.pl;
import com.google.common.collect.Maps;
import io.codearte.jfairy.producer.person.PassportNumberProvider;
import io.codearte.jfairy.producer.util.AlphaNumberSystem;
import java.util.List;
import java.util.Map;
import static java.lang.Character.getNumericValue;
import static java.lang.String.valueOf;
import static java.lang.System.arraycopy;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.apache.commons.lang3.RandomStringUtils.randomNumeric;
/**
* @author Olga Maciaszek-Sharma
* @since 21.02.15
*/
public class PlPassportNumberProvider implements PassportNumberProvider {
private static final int CHECKSUM_INDEX = 2;
private static final int[] WEIGHTS = new int[]{7, 3, 9, 1, 7, 3, 1, 7, 3};
private List<String> alphabet;
private static Map<String, Integer> letterDigits = null;
public PlPassportNumberProvider() {
alphabet = AlphaNumberSystem.generateAlphabetList();
letterDigits = generateLetterDigits();
}
private Map<String, Integer> generateLetterDigits() {
Integer baseNum = 10;
Map<String, Integer> letterDigits = Maps.newHashMap();
for (String letter : alphabet) {
letterDigits.put(letter, baseNum++);
}
return letterDigits;
}
@Override
public String get() {
char[] passport = new char[9];
fillSeries(passport);
fillDigits(passport);
fillChecksum(passport);
return valueOf(passport);
}
private void fillChecksum(char[] passport) {
Integer checkSum = 0;
for (int i = 0; i < 2; i++) {
Integer checkSumValue = letterDigits.get(valueOf(passport[i]));
checkSum += checkSumValue * WEIGHTS[i];
}
for (int i = 3; i < 9; i++) {
Integer checkSumValue = getNumericValue(passport[i]);
checkSum += checkSumValue * WEIGHTS[i];
}
passport[CHECKSUM_INDEX] = Integer.toString(checkSum % 10).charAt(0);
}
private void fillSeries(char[] passport) {
char[] randomSeries = randomAlphabetic(2).toUpperCase().toCharArray();
arraycopy(randomSeries, 0, passport, 0, randomSeries.length);
}
private void fillDigits(char[] passport) {
char[] randomDigits = randomNumeric(6).toCharArray();
arraycopy(randomDigits, 0, passport, 3, randomDigits.length);
}
public static Boolean passportCheckSumIsValid(String passportNumber) {
char[] passport = passportNumber.toCharArray();
int checkSum = 0;
for (int i = 0; i < 2; i++) {
Integer checkSumValue = letterDigits.get(valueOf(passport[i]));
checkSum += checkSumValue * WEIGHTS[i];
}
for (int i = 2; i < 9; i++) {
Integer checkSumValue = getNumericValue(passport[i]);
checkSum += checkSumValue * WEIGHTS[i];
}
return checkSum % 10 == 0;
}
}