/*
 * 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.mixnet.commons.tools;

import com.scytl.products.ov.mixnet.commons.beans.IntPair;
import org.apache.commons.lang3.NotImplementedException;

import java.util.ArrayList;
import java.util.List;

public class IntPairCalculator {

    private final List<IntPair> list;

    public IntPairCalculator() {
        list = new ArrayList<>();
    }

    public List<IntPair> computeTwoAddendsCombinations(final int number) {

        validateInput(number);

        int firstAddend = 1;
        int secondAddend = number - 1;

        while (firstAddend <= secondAddend) {

            final IntPair pair = new IntPair(firstAddend, secondAddend);

            list.add(pair);

            firstAddend++;
            secondAddend--;
        }
        return list;
    }

    /**
     * @param N
     * @return
     */
    public List<IntPair> generateTwoFactorCombinationsWithoutOnes(final int N) {

        validateInput(N);

        List<IntPair> combinations = new ArrayList<>();

        int divisor = 2;
        while (divisor <= N / 2) {
            // during the above division, the decimal part of the result of the division is discarded, effectively
            // a floor operation is performed.
            if (N % divisor == 0) {

                IntPair mnCombination1 = new IntPair(N / divisor, divisor);

                combinations.add(mnCombination1);
            }

            divisor++;
        }

        return combinations;
    }

    /**
     * @param N
     * @return
     */
    public List<IntPair> generateAllTwoFactorCombinations(final int N) {

        validateInput(N);

        List<IntPair> combinations = generateTwoFactorCombinationsWithoutOnes(N);

        combinations.add(new IntPair(1, N));
        combinations.add(new IntPair(N, 1));
        return combinations;
    }

    /**
     * @param N
     * @return
     */
    public List<IntPair> getMostOptimalCombination(final int N) {

        throw new NotImplementedException("Pending code the table of best parameter values");

    }

    private static void validateInput(final int number) {
        if (number == Integer.MAX_VALUE || number == Integer.MIN_VALUE) {
            throw new IllegalArgumentException(
                "The given number should be a value between MAX and MIN Integer value (not included)");
        }
    }

}
