/*
 * 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.core.source32;

import java.util.stream.Stream;
import org.apache.commons.rng.LongJumpableUniformRandomProvider;
import org.apache.commons.rng.core.RandomAssert;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

/**
 * Test for {@link L32X64Mix}.
 */
class L32X64MixTest extends AbstractLXMTest {

    /**
     * Factory to create a composite LXM generator that is equivalent
     * to the RNG under test.
     */
    private static class Factory implements LXMGeneratorFactory {
        static final Factory INSTANCE = new Factory();

        @Override
        public int lcgSeedSize() {
            return 2;
        }

        @Override
        public int xbgSeedSize() {
            return 2;
        }

        @Override
        public LXMGenerator create(int[] seed) {
            return new LXMGenerator(getMix(),
                                    new LCG32(seed[0], seed[1]),
                                    new XBGXoRoShiRo64(seed[2], seed[3]));
        }
    }

    @Override
    LXMGeneratorFactory getFactory() {
        return Factory.INSTANCE;
    }

    @Override
    LongJumpableUniformRandomProvider create(int[] seed) {
        return new L32X64Mix(seed);
    }

    @Override
    Stream<Arguments> getReferenceData() {
        /*
         * Reference data from JDK 17:
         * java.util.random.RandomGeneratorFactory.of("L32X64MixRandom").create(seed)
         *
         * Full byte[] seed created using SecureRandom.nextBytes. The seed was converted
         * to int[] by filling the long bits sequentially starting at the most
         * significant byte matching the method used by JDK 17. A sign extension bug in
         * byte[] conversion required all byte indices (i % 4 != 0) to be non-negative.
         * See: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8282144
         *
         * Note: Seed order: LCG addition; LCG state; XBG state.
         */
        return Stream.of(
            Arguments.of(
                new int[] {
                    0x5a16253f, 0xd449657e, 0x5b46012d, 0x1d504d64,
                },
                new int[] {
                    0xa6cc8f9b, 0xb9d3f0e3, 0xb8861d42, 0x9f8001a2,
                    0xaf1eea5b, 0x4e3bc947, 0x1c6378b8, 0x54ccc942,
                    0x4629da71, 0x0126a7e7, 0x6038f89c, 0xff72cb5c,
                    0x3853ae58, 0xc86ccf16, 0x02d32147, 0x78afed22,
                    0x432194a4, 0xf79809aa, 0x8c115507, 0x646b0445,
                    0xed63cc9c, 0x4e1d7b55, 0x699cf21d, 0x7d2adf74,
                    0xc2613634, 0x5ac9c96f, 0x1f2e59d2, 0x4c9878fb,
                    0x49c7a137, 0xd277cdf8, 0x369dd190, 0x1edeb2dc,
                    0x10bd09bd, 0x86e5140c, 0xe6bcb04c, 0x67f97775,
                    0x8f979b43, 0x36dfa266, 0x3acf5157, 0xe69aac08,
                }),
            Arguments.of(
                new int[] {
                    0xa3512c5b, 0x970f3100, 0xfc22313b, 0xa71f183a,
                },
                new int[] {
                    0x971dc6d7, 0xd8200b05, 0x0093d467, 0x74f11b96,
                    0x8945aa8f, 0x88a3d635, 0xb1fcb212, 0x66ed8543,
                    0xd5970056, 0x7b8b2d89, 0xd2d3957b, 0xc4ecc777,
                    0xf8e295c3, 0x4ffb4a29, 0x509fc6b0, 0x9c5b1965,
                    0x5008c757, 0x3a19410a, 0xc3992498, 0x0c4a8f22,
                    0x3f6abfd8, 0xe943ac45, 0xb632fcd3, 0x3d1f3201,
                    0xb17bc9f5, 0x902a9b9c, 0x39a76388, 0xd8c856a0,
                    0x7422cf86, 0x3f776592, 0xef70a122, 0x053b628e,
                    0x0dec8c4e, 0x5b0d80c9, 0xf58d19fc, 0x741f1361,
                    0x01b747f7, 0x6b325a32, 0x714ed761, 0xf1facf8e,
                }),
            Arguments.of(
                new int[] {
                    0x17767167, 0x1b6e286c, 0xe84a2f12, 0x637a5034,
                },
                new int[] {
                    0xd69fd4c1, 0x134945f8, 0x34c2fd4e, 0xd152b08f,
                    0xb5a7e2bd, 0xd8afab0d, 0xed15f9d2, 0x6baba06e,
                    0x9a1e8bcd, 0x8b392fbd, 0xb1e1cad9, 0x929f06d9,
                    0xc9467860, 0x3d492690, 0x84fd7d06, 0xb576b0f9,
                    0x860eac4c, 0xd3b7aa5b, 0x3ff4dd13, 0xfea00d01,
                    0x025143a0, 0xf1c5885a, 0x3041a8be, 0xbfbfb908,
                    0x186cd9cc, 0x1771875b, 0x9cc65fe2, 0xc9189702,
                    0x6063b09d, 0x20f0286b, 0x6094b83d, 0x8c3fe8f5,
                    0x2bf720eb, 0xe229e207, 0xe33f93db, 0x443b3849,
                    0x79cc70a8, 0xcbf0de84, 0xe57c6367, 0xe555ee21,
                }));
    }

    @ParameterizedTest
    @MethodSource(value = "getReferenceData")
    void testElementConstructor(int[] seed, int[] expected) {
        final L32X64Mix rng1 = new L32X64Mix(seed);
        final L32X64Mix rng2 = new L32X64Mix(seed[0], seed[1], seed[2], seed[3]);
        RandomAssert.assertNextLongEquals(seed.length * 2, rng1, rng2);
    }
}
