/*
 * 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.shuffler.permutation;

import com.scytl.products.ov.mixnet.commons.beans.Permutation;

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

/**
 * Permits the application of a permutation to a list of elements.
 */
public final class Permutator {

    /**
     * Create a new list containing the same elements as those in {@code list},
     * but in which the order of the elements are permutated according to
     * {@code permutation}. All of the elements in {@code permutation} should be
     * indexes of {@code list}.
     *
     * @param list
     *            the list to be permutated.
     * @param permutation
     *            the permutation to be applied to the new list.
     * @throws IllegalArgumentException
     *             if either of the arguments are not initialized or don't
     *             contain at least two elements.
     * @throws IllegalArgumentException
     *             if the sizes of the arguments are not equal.
     */
    public <T> List<T> createPermutatedList(final List<T> list,
            final Permutation permutation) {

        validateInputs(list, permutation);

        List<T> permutatedList = new ArrayList<>(list.size());

        for (int i = 0, permutationLength = permutation.getLength(); i < permutationLength; i++) {
            final int sourceIndex = permutation.destinationOf(i);
            permutatedList.add(list.get(sourceIndex));
        }

        return permutatedList;
    }

    private static <T> void validateInputs(final List<T> list,
            final Permutation permutation) {

        if (list == null || (list.isEmpty())) {
            throw new IllegalArgumentException(
                "An initialized list, with at least 1 elemement must be received.");
        }

        if (permutation == null) {
            throw new IllegalArgumentException(
                "An initialized permutation must be received.");
        }

        if (list.size() != permutation.getLength()) {
            throw new IllegalArgumentException(
                "The sizes of the list of elements and the permutation must be the same.");
        }

    }
}
