/*
 * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @summary Verify nextDouble stays within range
 * @bug 8280550 8280950 8281183 8202449
 *
 * @key randomness
 * @library /test/lib
 * @build jdk.test.lib.RandomFactory
 * @run main RandomNextDoubleBoundary

 */

import java.util.SplittableRandom;
import java.util.random.RandomGenerator;
import jdk.test.lib.RandomFactory;

public class RandomNextDoubleBoundary {
    public static void main(String... args) {
        negativeBounds();
        positiveBounds();
        nextDoubleHugeRange();
    }

    private static void negativeBounds() {
        // Both bounds are negative
        double lowerBound = -1.0000000000000002;
        double upperBound = -1.0;
        var sr = new SplittableRandom(42L);
        var r = sr.nextDouble(lowerBound, upperBound);

        if (r >= upperBound) {
            System.err.println("r = " + r + "\t" + Double.toHexString(r));
            System.err.println("ub = " + upperBound + "\t" + Double.toHexString(upperBound));
            throw new RuntimeException("Greater than upper bound");
        }

        if (r < lowerBound) {
            System.err.println("r = " + r + "\t" + Double.toHexString(r));
            System.err.println("lb = " + lowerBound + "\t" + Double.toHexString(lowerBound));
            throw new RuntimeException("Less than lower bound");
        }
    }

    private static void positiveBounds() {
        double[][] originAndBounds = {{10, 100},
                                      {12345, 123456},
                                      {5432167.234, 54321678.1238}};
        for (double[] originAndBound : originAndBounds) {
            nextDoublesWithRange(originAndBound[0], originAndBound[1]);
        }
    }

    public static void nextDoublesWithRange(double origin, double bound) {
        RandomGenerator rg = new RandomGenerator() {
            @Override
            public double nextDouble() {
                return Double.MAX_VALUE;
            }

            @Override
            public long nextLong() {
                return 0;
            }
        };
        double value = rg.nextDouble(origin, bound);

        if (bound > 0) {
            value = rg.nextDouble(bound); // Equivalent to nextDouble(0.0, bound)
            assertTrue(value >= 0.0);
            assertTrue(value < bound);
        }
    }

    public static void nextDoubleHugeRange() {
        var random = RandomFactory.getRandom();
        var n = 100_000;

        var origin = -(3.0 / 4.0) * Double.MAX_VALUE;
        var bound = (3.0 / 4.0) * Double.MAX_VALUE;
        assertTrue(bound - origin == Double.POSITIVE_INFINITY);

        /* all are within [origin, bound) */
        assertTrue(random.doubles(n, origin, bound)
                .allMatch(d -> origin <= d && d < bound));

        /* some are near the origin */
        assertTrue(random.doubles(n, origin, bound)
                .anyMatch(d -> d < (15.0 / 16.0) * origin));

        /* some are near the bound */
        assertTrue(random.doubles(n, origin, bound)
                .anyMatch(d -> d > (15.0 / 16.0) * bound));
    }

    public static void assertTrue(boolean condition) {
        if (!condition) {
            throw new AssertionError();
        }
    }

}
