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

import java.util.Arrays;
import org.apache.commons.rng.core.util.NumberFactory;

/**
 * This class provides the 64-bits version of the originally 32-bits
 * {@link org.apache.commons.rng.core.source32.MersenneTwister
 * Mersenne Twister}.
 *
 * <p>
 * This class is mainly a Java port of
 * <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt64.html">
 *  the 2014/2/23 version of the generator
 * </a> written in C by Takuji Nishimura and Makoto Matsumoto.
 * </p>
 *
 * <p>
 * Here is their original copyright:
 * </p>
 *
 * <table style="background-color: #E0E0E0; width: 80%">
 * <caption>Mersenne Twister licence</caption>
 * <tr><td style="padding: 10px">Copyright (C) 2004, Makoto Matsumoto and Takuji Nishimura,
 *     All rights reserved.</td></tr>
 *
 * <tr><td style="padding: 10px">Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * <ol>
 *   <li>Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.</li>
 *   <li>Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.</li>
 *   <li>The names of its contributors may not be used to endorse or promote
 *       products derived from this software without specific prior written
 *       permission.</li>
 * </ol></td></tr>
 *
 * <tr><td style="padding: 10px"><strong>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.</strong></td></tr>
 * </table>
 *
 * @see <a href="https://en.wikipedia.org/wiki/Mersenne_Twister">Mersenne Twister (Wikipedia)</a>
 * @since 1.0
 */
public class MersenneTwister64 extends LongProvider {
    /** Size of the bytes pool. */
    private static final int NN = 312;
    /** Period second parameter. */
    private static final int MM = 156;
    /** X * MATRIX_A for X = {0, 1}. */
    private static final long[] MAG01 = {0x0L, 0xb5026f5aa96619e9L};
    /** Most significant 33 bits. */
    private static final long UM = 0xffffffff80000000L;
    /** Least significant 31 bits. */
    private static final long LM = 0x7fffffffL;
    /** Bytes pool. */
    private final long[] mt = new long[NN];
    /** Current index in the bytes pool. */
    private int mti;

    /**
     * Creates a new random number generator.
     *
     * @param seed Initial seed.
     */
    public MersenneTwister64(long[] seed) {
        setSeedInternal(seed);
    }

    /** {@inheritDoc} */
    @Override
    protected byte[] getStateInternal() {
        final long[] s = Arrays.copyOf(mt, NN + 1);
        s[NN] = mti;

        return composeStateInternal(NumberFactory.makeByteArray(s),
                                    super.getStateInternal());
    }

    /** {@inheritDoc} */
    @Override
    protected void setStateInternal(byte[] s) {
        final byte[][] c = splitStateInternal(s, (NN + 1) * 8);

        final long[] tmp = NumberFactory.makeLongArray(c[0]);
        System.arraycopy(tmp, 0, mt, 0, NN);
        mti = (int) tmp[NN];

        super.setStateInternal(c[1]);
    }

    /**
     * Initializes the generator with the given seed.
     *
     * @param inputSeed Initial seed.
     */
    private void setSeedInternal(long[] inputSeed) {
        // Accept empty seed.
        final long[] seed = (inputSeed.length == 0) ? new long[1] : inputSeed;

        initState(19650218L);
        int i = 1;
        int j = 0;

        for (int k = Math.max(NN, seed.length); k != 0; k--) {
            final long mm1 = mt[i - 1];
            mt[i] = (mt[i] ^ ((mm1 ^ (mm1 >>> 62)) * 0x369dea0f31a53f85L)) + seed[j] + j; // non linear
            i++;
            j++;
            if (i >= NN) {
                mt[0] = mt[NN - 1];
                i = 1;
            }
            if (j >= seed.length) {
                j = 0;
            }
        }
        for (int k = NN - 1; k != 0; k--) {
            final long mm1 = mt[i - 1];
            mt[i] = (mt[i] ^ ((mm1 ^ (mm1 >>> 62)) * 0x27bb2ee687b0b0fdL)) - i; // non linear
            i++;
            if (i >= NN) {
                mt[0] = mt[NN - 1];
                i = 1;
            }
        }

        mt[0] = 0x8000000000000000L; // MSB is 1; assuring non-zero initial array
    }

    /**
     * Initialize the internal state of this instance.
     *
     * @param seed Seed.
     */
    private void initState(long seed) {
        mt[0] = seed;
        for (mti = 1; mti < NN; mti++) {
            final long mm1 = mt[mti - 1];
            mt[mti] = 0x5851f42d4c957f2dL * (mm1 ^ (mm1 >>> 62)) + mti;
        }
    }

    /** {@inheritDoc} */
    @Override
    public long next() {
        long x;

        if (mti >= NN) { // generate NN words at one time
            for (int i = 0; i < NN - MM; i++) {
                x = (mt[i] & UM) | (mt[i + 1] & LM);
                mt[i] = mt[i + MM] ^ (x >>> 1) ^ MAG01[(int)(x & 0x1L)];
            }
            for (int i = NN - MM; i < NN - 1; i++) {
                x = (mt[i] & UM) | (mt[i + 1] & LM);
                mt[i] = mt[ i + (MM - NN)] ^ (x >>> 1) ^ MAG01[(int)(x & 0x1L)];
            }

            x = (mt[NN - 1] & UM) | (mt[0] & LM);
            mt[NN - 1] = mt[MM - 1] ^ (x >>> 1) ^ MAG01[(int)(x & 0x1L)];

            mti = 0;
        }

        x = mt[mti++];

        x ^= (x >>> 29) & 0x5555555555555555L;
        x ^= (x << 17) & 0x71d67fffeda60000L;
        x ^= (x << 37) & 0xfff7eee000000000L;
        x ^= x >>> 43;

        return x;
    }
}
