/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.rng.simple.internal;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import org.apache.commons.rng.UniformRandomProvider;
import org.apache.commons.rng.RestorableUniformRandomProvider;
import org.apache.commons.rng.core.source32.JDKRandom;
import org.apache.commons.rng.core.source32.Well512a;
import org.apache.commons.rng.core.source32.Well1024a;
import org.apache.commons.rng.core.source32.Well19937a;
import org.apache.commons.rng.core.source32.Well19937c;
import org.apache.commons.rng.core.source32.Well44497a;
import org.apache.commons.rng.core.source32.Well44497b;
import org.apache.commons.rng.core.source32.ISAACRandom;
import org.apache.commons.rng.core.source32.IntProvider;
import org.apache.commons.rng.core.source32.MersenneTwister;
import org.apache.commons.rng.core.source32.MiddleSquareWeylSequence;
import org.apache.commons.rng.core.source32.MultiplyWithCarry256;
import org.apache.commons.rng.core.source32.KISSRandom;
import org.apache.commons.rng.core.source32.XoRoShiRo64Star;
import org.apache.commons.rng.core.source32.XoRoShiRo64StarStar;
import org.apache.commons.rng.core.source32.XoShiRo128Plus;
import org.apache.commons.rng.core.source32.XoShiRo128PlusPlus;
import org.apache.commons.rng.core.source32.XoShiRo128StarStar;
import org.apache.commons.rng.core.source32.PcgXshRr32;
import org.apache.commons.rng.core.source32.PcgXshRs32;
import org.apache.commons.rng.core.source32.PcgMcgXshRr32;
import org.apache.commons.rng.core.source32.PcgMcgXshRs32;
import org.apache.commons.rng.core.source32.DotyHumphreySmallFastCounting32;
import org.apache.commons.rng.core.source32.JenkinsSmallFast32;
import org.apache.commons.rng.core.source32.L32X64Mix;
import org.apache.commons.rng.core.source64.SplitMix64;
import org.apache.commons.rng.core.source64.XorShift1024Star;
import org.apache.commons.rng.core.source64.XorShift1024StarPhi;
import org.apache.commons.rng.core.source64.TwoCmres;
import org.apache.commons.rng.core.source64.XoRoShiRo1024PlusPlus;
import org.apache.commons.rng.core.source64.XoRoShiRo1024Star;
import org.apache.commons.rng.core.source64.XoRoShiRo1024StarStar;
import org.apache.commons.rng.core.source64.MersenneTwister64;
import org.apache.commons.rng.core.source64.XoRoShiRo128Plus;
import org.apache.commons.rng.core.source64.XoRoShiRo128PlusPlus;
import org.apache.commons.rng.core.source64.XoRoShiRo128StarStar;
import org.apache.commons.rng.core.source64.XoShiRo256Plus;
import org.apache.commons.rng.core.source64.XoShiRo256PlusPlus;
import org.apache.commons.rng.core.source64.XoShiRo256StarStar;
import org.apache.commons.rng.core.source64.XoShiRo512Plus;
import org.apache.commons.rng.core.source64.XoShiRo512PlusPlus;
import org.apache.commons.rng.core.source64.XoShiRo512StarStar;
import org.apache.commons.rng.core.source64.PcgRxsMXs64;
import org.apache.commons.rng.core.source64.DotyHumphreySmallFastCounting64;
import org.apache.commons.rng.core.source64.JenkinsSmallFast64;
import org.apache.commons.rng.core.source64.L64X1024Mix;
import org.apache.commons.rng.core.source64.L64X128Mix;
import org.apache.commons.rng.core.source64.L64X128StarStar;
import org.apache.commons.rng.core.source64.L64X256Mix;
import org.apache.commons.rng.core.source64.L128X1024Mix;
import org.apache.commons.rng.core.source64.L128X128Mix;
import org.apache.commons.rng.core.source64.L128X256Mix;

/**
 * RNG builder.
 * <p>
 * It uses reflection to find the factory method of the RNG implementation,
 * and performs seed type conversions.
 * </p>
 */
public final class ProviderBuilder {
    /** Error message. */
    private static final String INTERNAL_ERROR_MSG = "Internal error: Please file a bug report";

    /**
     * Class only contains static method.
     */
    private ProviderBuilder() {}

    /**
     * Creates a RNG instance.
     *
     * @param source RNG specification.
     * @return a new RNG instance.
     * @throws IllegalArgumentException if argument data to initialize the
     * generator implemented by the given {@code source} is missing.
     * @since 1.3
     */
    public static RestorableUniformRandomProvider create(RandomSourceInternal source) {
        // Delegate to the random source allowing generator specific implementations.
        return source.create();
    }

    /**
     * Creates a RNG instance.
     *
     * @param source RNG specification.
     * @param seed Seed value.  It can be {@code null} (in which case a
     * random value will be used).
     * @param args Additional arguments to the implementation's constructor.
     * @return a new RNG instance.
     * @throws UnsupportedOperationException if the seed type is invalid.
     * @throws IllegalArgumentException if argument data to initialize the
     * generator implemented by the given {@code source} is invalid.
     */
    public static RestorableUniformRandomProvider create(RandomSourceInternal source,
                                                         Object seed,
                                                         Object[] args) {
        // Delegate to the random source allowing generator specific implementations.
        // This method checks arguments for null and calls the appropriate internal method.
        if (args != null) {
            return source.create(seed, args);
        }
        return seed == null ?
                source.create() :
                source.create(seed);
    }

    /**
     * Identifiers of the generators.
     */
    public enum RandomSourceInternal {
        /** Source of randomness is {@link JDKRandom}. */
        JDK(JDKRandom.class,
            1,
            NativeSeedType.LONG),
        /** Source of randomness is {@link Well512a}. */
        WELL_512_A(Well512a.class,
                   16, 0, 16,
                   NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link Well1024a}. */
        WELL_1024_A(Well1024a.class,
                    32, 0, 32,
                    NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link Well19937a}. */
        WELL_19937_A(Well19937a.class,
                     624, 0, 623,
                     NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link Well19937c}. */
        WELL_19937_C(Well19937c.class,
                     624, 0, 623,
                     NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link Well44497a}. */
        WELL_44497_A(Well44497a.class,
                     1391, 0, 1390,
                     NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link Well44497b}. */
        WELL_44497_B(Well44497b.class,
                     1391, 0, 1390,
                     NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link MersenneTwister}. */
        MT(MersenneTwister.class,
           624,
           NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link ISAACRandom}. */
        ISAAC(ISAACRandom.class,
              256,
              NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link SplitMix64}. */
        SPLIT_MIX_64(SplitMix64.class,
                     1,
                     NativeSeedType.LONG),
        /** Source of randomness is {@link XorShift1024Star}. */
        XOR_SHIFT_1024_S(XorShift1024Star.class,
                         16, 0, 16,
                         NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link TwoCmres}. */
        TWO_CMRES(TwoCmres.class,
                  1,
                  NativeSeedType.INT),
        /**
         * Source of randomness is {@link TwoCmres} with explicit selection
         * of the two subcycle generators.
         */
        TWO_CMRES_SELECT(TwoCmres.class,
                         1,
                         NativeSeedType.INT,
                         Integer.TYPE,
                         Integer.TYPE),
        /** Source of randomness is {@link MersenneTwister64}. */
        MT_64(MersenneTwister64.class,
              312,
              NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link MultiplyWithCarry256}. */
        MWC_256(MultiplyWithCarry256.class,
                257, 0, 257,
                NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link KISSRandom}. */
        KISS(KISSRandom.class,
             // If zero in initial 3 positions the output is a simple LCG
             4, 0, 3,
             NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link XorShift1024StarPhi}. */
        XOR_SHIFT_1024_S_PHI(XorShift1024StarPhi.class,
                             16, 0, 16,
                             NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link XoRoShiRo64Star}. */
        XO_RO_SHI_RO_64_S(XoRoShiRo64Star.class,
                          2, 0, 2,
                          NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link XoRoShiRo64StarStar}. */
        XO_RO_SHI_RO_64_SS(XoRoShiRo64StarStar.class,
                           2, 0, 2,
                           NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link XoShiRo128Plus}. */
        XO_SHI_RO_128_PLUS(XoShiRo128Plus.class,
                           4, 0, 4,
                           NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link XoShiRo128StarStar}. */
        XO_SHI_RO_128_SS(XoShiRo128StarStar.class,
                         4, 0, 4,
                         NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link XoRoShiRo128Plus}. */
        XO_RO_SHI_RO_128_PLUS(XoRoShiRo128Plus.class,
                              2, 0, 2,
                              NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link XoRoShiRo128StarStar}. */
        XO_RO_SHI_RO_128_SS(XoRoShiRo128StarStar.class,
                            2, 0, 2,
                            NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link XoShiRo256Plus}. */
        XO_SHI_RO_256_PLUS(XoShiRo256Plus.class,
                           4, 0, 4,
                           NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link XoShiRo256StarStar}. */
        XO_SHI_RO_256_SS(XoShiRo256StarStar.class,
                         4, 0, 4,
                         NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link XoShiRo512Plus}. */
        XO_SHI_RO_512_PLUS(XoShiRo512Plus.class,
                           8, 0, 8,
                           NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link XoShiRo512StarStar}. */
        XO_SHI_RO_512_SS(XoShiRo512StarStar.class,
                         8, 0, 8,
                         NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link PcgXshRr32}. */
        PCG_XSH_RR_32(PcgXshRr32.class,
                2,
                NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link PcgXshRs32}. */
        PCG_XSH_RS_32(PcgXshRs32.class,
                2,
                NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link PcgRxsMXs64}. */
        PCG_RXS_M_XS_64(PcgRxsMXs64.class,
                2,
                NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link PcgMcgXshRr32}. */
        PCG_MCG_XSH_RR_32(PcgMcgXshRr32.class,
                1,
                NativeSeedType.LONG),
        /** Source of randomness is {@link PcgMcgXshRs32}. */
        PCG_MCG_XSH_RS_32(PcgMcgXshRs32.class,
                1,
                NativeSeedType.LONG),
        /** Source of randomness is {@link MiddleSquareWeylSequence}. */
        MSWS(MiddleSquareWeylSequence.class,
             // Many partially zero seeds can create low quality initial output.
             // The Weyl increment cascades bits into the random state so ideally it
             // has a high number of bit transitions. Minimally ensure it is non-zero.
             3, 2, 3,
             NativeSeedType.LONG_ARRAY) {
            @Override
            protected Object createSeed() {
                return createMswsSeed(SeedFactory.createLong());
            }

            @Override
            protected Object convertSeed(Object seed) {
                // Allow seeding with primitives to generate a good seed
                if (seed instanceof Integer) {
                    return createMswsSeed((Integer) seed);
                } else if (seed instanceof Long) {
                    return createMswsSeed((Long) seed);
                }
                // Other types (e.g. the native long[]) are handled by the default conversion
                return super.convertSeed(seed);
            }

            @Override
            protected byte[] createByteArraySeed(UniformRandomProvider source) {
                // The seed requires approximately 4-6 calls to nextInt().
                // Wrap the input and switch to a default if the input is faulty.
                final UniformRandomProvider wrapped = new IntProvider() {
                    /** The number of remaining calls to the source generator. */
                    private int calls = 100;
                    /** Default generator, initialised when required. */
                    private UniformRandomProvider defaultGen;
                    @Override
                    public int next() {
                        if (calls == 0) {
                            // The input source is broken.
                            // Seed a default
                            if (defaultGen == null) {
                                defaultGen = new SplitMix64(source.nextLong());
                            }
                            return defaultGen.nextInt();
                        }
                        calls--;
                        return source.nextInt();
                    }
                    @Override
                    public long nextLong() {
                        // No specific requirements so always use the source
                        return source.nextLong();
                    }
                };
                return NativeSeedType.convertSeedToBytes(createMswsSeed(wrapped));
            }

            /**
             * Creates the full length seed array from the input seed.
             *
             * @param seed the seed
             * @return the seed array
             */
            private long[] createMswsSeed(long seed) {
                return createMswsSeed(new SplitMix64(seed));
            }

            /**
             * Creates the full length seed array from the input seed using the method
             * recommended for the generator. This is a high quality Weyl increment composed
             * of a hex character permutation.
             *
             * @param source Source of randomness.
             * @return the seed array
             */
            private long[] createMswsSeed(UniformRandomProvider source) {
                final long increment = SeedUtils.createLongHexPermutation(source);
                // The initial state should not be low complexity but the Weyl
                // state can be any number.
                final long state = increment;
                final long weylState = source.nextLong();
                return new long[] {state, weylState, increment};
            }
        },
        /** Source of randomness is {@link DotyHumphreySmallFastCounting32}. */
        SFC_32(DotyHumphreySmallFastCounting32.class,
               3,
               NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link DotyHumphreySmallFastCounting64}. */
        SFC_64(DotyHumphreySmallFastCounting64.class,
               3,
               NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link JenkinsSmallFast32}. */
        JSF_32(JenkinsSmallFast32.class,
               1,
               NativeSeedType.INT),
        /** Source of randomness is {@link JenkinsSmallFast64}. */
        JSF_64(JenkinsSmallFast64.class,
               1,
               NativeSeedType.LONG),
        /** Source of randomness is {@link XoShiRo128PlusPlus}. */
        XO_SHI_RO_128_PP(XoShiRo128PlusPlus.class,
                         4, 0, 4,
                         NativeSeedType.INT_ARRAY),
        /** Source of randomness is {@link XoRoShiRo128PlusPlus}. */
        XO_RO_SHI_RO_128_PP(XoRoShiRo128PlusPlus.class,
                            2, 0, 2,
                            NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link XoShiRo256PlusPlus}. */
        XO_SHI_RO_256_PP(XoShiRo256PlusPlus.class,
                         4, 0, 4,
                         NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link XoShiRo512PlusPlus}. */
        XO_SHI_RO_512_PP(XoShiRo512PlusPlus.class,
                         8, 0, 8,
                         NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link XoRoShiRo1024PlusPlus}. */
        XO_RO_SHI_RO_1024_PP(XoRoShiRo1024PlusPlus.class,
                             16, 0, 16,
                             NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link XoRoShiRo1024Star}. */
        XO_RO_SHI_RO_1024_S(XoRoShiRo1024Star.class,
                            16, 0, 16,
                            NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link XoRoShiRo1024StarStar}. */
        XO_RO_SHI_RO_1024_SS(XoRoShiRo1024StarStar.class,
                             16, 0, 16,
                             NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link PcgXshRr32}. */
        PCG_XSH_RR_32_OS(PcgXshRr32.class,
                1,
                NativeSeedType.LONG),
        /** Source of randomness is {@link PcgXshRs32}. */
        PCG_XSH_RS_32_OS(PcgXshRs32.class,
                1,
                NativeSeedType.LONG),
        /** Source of randomness is {@link PcgRxsMXs64}. */
        PCG_RXS_M_XS_64_OS(PcgRxsMXs64.class,
                1,
                NativeSeedType.LONG),
        /** Source of randomness is {@link L64X128StarStar}. */
        L64_X128_SS(L64X128StarStar.class,
                4, 2, 4,
                NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link L64X128Mix}. */
        L64_X128_MIX(L64X128Mix.class,
                4, 2, 4,
                NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link L64X256Mix}. */
        L64_X256_MIX(L64X256Mix.class,
                6, 2, 6,
                NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link L64X1024Mix}. */
        L64_X1024_MIX(L64X1024Mix.class,
                18, 2, 18,
                NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link L128X128Mix}. */
        L128_X128_MIX(L128X128Mix.class,
                6, 4, 6,
                NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link L128X256Mix}. */
        L128_X256_MIX(L128X256Mix.class,
                8, 4, 8,
                NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link L128X1024Mix}. */
        L128_X1024_MIX(L128X1024Mix.class,
                20, 4, 20,
                NativeSeedType.LONG_ARRAY),
        /** Source of randomness is {@link L32X64Mix}. */
        L32_X64_MIX(L32X64Mix.class,
                4, 2, 4,
                NativeSeedType.INT_ARRAY);

        /** Source type. */
        private final Class<? extends UniformRandomProvider> rng;
        /** Native seed size. Used for array seeds. */
        private final int nativeSeedSize;
        /** Start of the not all-zero sub-range for array seeds (inclusive). */
        private final int notAllZeroFrom;
        /** End of the not all-zero sub-range for array seeds (exclusive). */
        private final int notAllZeroTo;
        /** Define the parameter types of the data needed to build the generator. */
        private final Class<?>[] args;
        /** Native seed type. Used to create a seed or convert input seeds. */
        private final NativeSeedType nativeSeedType;
        /**
         * The constructor.
         * This is discovered using the constructor parameter types and stored for re-use.
         */
        private Constructor<?> rngConstructor;

        /**
         * Create a new instance.
         *
         * <p>Used when the seed array has no requirement for a not all-zero sub-range.
         *
         * @param rng Source type.
         * @param nativeSeedSize Native seed size (array types only).
         * @param nativeSeedType Native seed type.
         * @param args Additional data needed to create a generator instance.
         */
        RandomSourceInternal(Class<? extends UniformRandomProvider> rng,
                             int nativeSeedSize,
                             NativeSeedType nativeSeedType,
                             Class<?>... args) {
            this(rng, nativeSeedSize, 0, 0, nativeSeedType, args);
        }

        /**
         * Create a new instance.
         *
         * <p>Note: The sub-range of an array seed that is not all-zero can be specified.
         * If the native seed array is used to represent a number of bits
         * that is not an exact multiple of the number of bytes in the seed, then a
         * safe approach is to specify the sub-range using a smaller size than the
         * full length seed. For example a {@link Well19937a} generator uses 19937
         * bits and has a seed bit length of 19968. A safe range is [0, 19937 / 32).
         *
         * @param rng Source type.
         * @param nativeSeedSize Native seed size (array types only).
         * @param notAllZeroFrom The start of the not all-zero sub-range (inclusive).
         * @param notAllZeroTo The end of the not all-zero sub-range (exclusive).
         * @param nativeSeedType Native seed type.
         * @param args Additional data needed to create a generator instance.
         */
        RandomSourceInternal(Class<? extends UniformRandomProvider> rng,
                             int nativeSeedSize,
                             int notAllZeroFrom,
                             int notAllZeroTo,
                             NativeSeedType nativeSeedType,
                             Class<?>... args) {
            this.rng = rng;
            this.nativeSeedSize = nativeSeedSize;
            this.notAllZeroFrom = notAllZeroFrom;
            this.notAllZeroTo = notAllZeroTo;
            this.nativeSeedType = nativeSeedType;
            // Build the complete list of class types for the constructor
            this.args = (Class<?>[]) Array.newInstance(args.getClass().getComponentType(), 1 + args.length);
            this.args[0] = nativeSeedType.getType();
            System.arraycopy(args, 0, this.args, 1, args.length);
        }

        /**
         * Gets the implementing class of the random source.
         *
         * @return the random source class.
         */
        public Class<?> getRng() {
            return rng;
        }

        /**
         * Gets the class of the native seed.
         *
         * @return the seed class.
         */
        Class<?> getSeed() {
            return args[0];
        }

        /**
         * Gets the parameter types of the data needed to build the generator.
         *
         * @return the data needed to build the generator.
         */
        Class<?>[] getArgs() {
            return args;
        }

        /**
         * Checks whether the type of given {@code seed} is the native type
         * of the implementation.
         *
         * @param <SEED> Seed type.
         *
         * @param seed Seed value.
         * @return {@code true} if the seed can be passed to the builder
         * for this RNG type.
         */
        public <SEED> boolean isNativeSeed(SEED seed) {
            return seed != null && getSeed().equals(seed.getClass());
        }

        /**
         * Creates a RNG instance.
         *
         * <p>This method can be over-ridden to allow fast construction of a generator
         * with low seeding cost that has no additional constructor arguments.</p>
         *
         * @return a new RNG instance.
         */
        RestorableUniformRandomProvider create() {
            // Create a seed.
            final Object nativeSeed = createSeed();
            // Instantiate.
            return create(getConstructor(), new Object[] {nativeSeed});
        }

        /**
         * Creates a RNG instance. It is assumed the seed is not {@code null}.
         *
         * <p>This method can be over-ridden to allow fast construction of a generator
         * with low seed conversion cost that has no additional constructor arguments.</p>
         *
         * @param seed Seed value. It must not be {@code null}.
         * @return a new RNG instance.
         * @throws UnsupportedOperationException if the seed type is invalid.
         */
        RestorableUniformRandomProvider create(Object seed) {
            // Convert seed to native type.
            final Object nativeSeed = convertSeed(seed);
            // Instantiate.
            return create(getConstructor(), new Object[] {nativeSeed});
        }

        /**
         * Creates a RNG instance. This constructs a RNG using reflection and will error
         * if the constructor arguments do not match those required by the RNG's constructor.
         *
         * @param seed Seed value. It can be {@code null} (in which case a suitable
         * seed will be generated).
         * @param constructorArgs Additional arguments to the implementation's constructor.
         * It must not be {@code null}.
         * @return a new RNG instance.
         * @throws UnsupportedOperationException if the seed type is invalid.
         */
        RestorableUniformRandomProvider create(Object seed,
                                               Object[] constructorArgs) {
            final Object nativeSeed = createNativeSeed(seed);

            // Build a single array with all the arguments to be passed
            // (in the right order) to the constructor.
            Object[] all = new Object[constructorArgs.length + 1];
            all[0] = nativeSeed;
            System.arraycopy(constructorArgs, 0, all, 1, constructorArgs.length);

            // Instantiate.
            return create(getConstructor(), all);
        }

        /**
         * Creates a native seed.
         *
         * <p>The default implementation creates a seed of the native type and, for array seeds,
         * ensures not all bits are zero.</p>
         *
         * <p>This method should be over-ridden to satisfy seed requirements for the generator.</p>
         *
         * @return the native seed
         * @since 1.3
         */
        protected Object createSeed() {
            // Ensure the seed is not all-zero in the sub-range
            return nativeSeedType.createSeed(nativeSeedSize, notAllZeroFrom, notAllZeroTo);
        }

        /**
         * Creates a {@code byte[]} seed using the provided source of randomness.
         *
         * <p>The default implementation creates a full-length seed and ensures not all bits
         * are zero.</p>
         *
         * <p>This method should be over-ridden to satisfy seed requirements for the generator.</p>
         *
         * @param source Source of randomness.
         * @return the byte[] seed
         * @since 1.3
         */
        protected byte[] createByteArraySeed(UniformRandomProvider source) {
            // Ensure the seed is not all-zero in the sub-range.
            // Note: Convert the native seed array size/positions to byte size/positions.
            final int bytes = nativeSeedType.getBytes();
            return SeedFactory.createByteArray(source,
                bytes * nativeSeedSize,
                bytes * notAllZeroFrom,
                bytes * notAllZeroTo);
        }

        /**
         * Converts a seed from any of the supported seed types to a native seed.
         *
         * <p>The default implementation delegates to the native seed type conversion.</p>
         *
         * <p>This method should be over-ridden to satisfy seed requirements for the generator.</p>
         *
         * @param seed Input seed (must not be null).
         * @return the native seed
         * @throws UnsupportedOperationException if the {@code seed} type is invalid.
         * @since 1.3
         */
        protected Object convertSeed(Object seed) {
            return nativeSeedType.convertSeed(seed, nativeSeedSize);
        }

        /**
         * Creates a native seed from any of the supported seed types.
         *
         * @param seed Input seed (may be null).
         * @return the native seed.
         * @throws UnsupportedOperationException if the {@code seed} type cannot be converted.
         */
        private Object createNativeSeed(Object seed) {
            return seed == null ?
                createSeed() :
                convertSeed(seed);
        }

        /**
         * Creates a seed suitable for the implementing class represented by this random source.
         *
         * <p>It will satisfy the seed size and any other seed requirements for the
         * implementing class. The seed is converted from the native type to bytes.</p>
         *
         * @return the seed bytes
         * @since 1.3
         */
        public final byte[] createSeedBytes() {
            // Custom implementations can override createSeed
            final Object seed = createSeed();
            return NativeSeedType.convertSeedToBytes(seed);
        }

        /**
         * Creates a seed suitable for the implementing class represented by this random source
         * using the supplied source of randomness.
         *
         * <p>It will satisfy the seed size and any other seed requirements for the
         * implementing class. The seed is converted from the native type to bytes.</p>
         *
         * @param source Source of randomness.
         * @return the seed bytes
         * @since 1.3
         */
        public final byte[] createSeedBytes(UniformRandomProvider source) {
            // Custom implementations can override createByteArraySeed
            return createByteArraySeed(source);
        }

        /**
         * Gets the constructor.
         *
         * @return the RNG constructor.
         */
        private Constructor<?> getConstructor() {
            // The constructor never changes so it is stored for re-use.
            Constructor<?> constructor = rngConstructor;
            if (constructor == null) {
                // If null this is either the first attempt to find it or
                // look-up previously failed and this method will throw
                // upon each invocation.
                constructor = createConstructor();
                rngConstructor = constructor;
            }
            return constructor;
        }

        /**
         * Creates a constructor.
         *
         * @return a RNG constructor.
         */
        private Constructor<?> createConstructor() {
            try {
                return getRng().getConstructor(getArgs());
            } catch (NoSuchMethodException e) {
                // Info in "RandomSourceInternal" is inconsistent with the
                // constructor of the implementation.
                throw new IllegalStateException(INTERNAL_ERROR_MSG, e);
            }
        }

        /**
         * Creates a RNG.
         *
         * @param rng RNG specification.
         * @param args Arguments to the implementation's constructor.
         * @return a new RNG instance.
         */
        private static RestorableUniformRandomProvider create(Constructor<?> rng,
                                                              Object[] args) {
            try {
                return (RestorableUniformRandomProvider) rng.newInstance(args);
            } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
                throw new IllegalStateException(INTERNAL_ERROR_MSG, e);
            }
        }
    }
}
