/*
 * Copyright (c) 1999, 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
 * @library /test/lib
 * @build jdk.test.lib.RandomFactory
 * @run main StringConstructor
 * @bug 4103117 4331084 4488017 4490929 6255285 6268365 8074460 8078672 8233760
 * @summary Tests the BigDecimal string constructor (use -Dseed=X to set PRNG seed).
 * @key randomness
 */

import java.math.*;
import java.util.Random;
import jdk.test.lib.RandomFactory;

public class StringConstructor {

    public static void main(String[] args) throws Exception {
        constructWithError("");
        constructWithError("+");
        constructWithError("-");
        constructWithError("+e");
        constructWithError("-e");
        constructWithError("e+");
        constructWithError("1.-0");
        constructWithError(".-123");
        constructWithError("-");
        constructWithError("--1.1");
        constructWithError("-+1.1");
        constructWithError("+-1.1");
        constructWithError("1-.1");
        constructWithError("1+.1");
        constructWithError("1.111+1");
        constructWithError("1.111-1");
        constructWithError("11.e+");
        constructWithError("11.e-");
        constructWithError("11.e+-");
        constructWithError("11.e-+");
        constructWithError("11.e-+1");
        constructWithError("11.e+-1");

        // Range checks
        constructWithError("1e"+Integer.MIN_VALUE);
        constructWithError("10e"+Integer.MIN_VALUE);
        constructWithError("0.01e"+Integer.MIN_VALUE);
        constructWithError("1e"+((long)Integer.MIN_VALUE-1));

        leadingExponentZeroTest();
        nonAsciiZeroTest();

        /* These BigDecimals produce a string with an exponent > Integer.MAX_VALUE */
        roundtripWithAbnormalExponent(BigDecimal.valueOf(10, Integer.MIN_VALUE));
        roundtripWithAbnormalExponent(BigDecimal.valueOf(Long.MIN_VALUE, Integer.MIN_VALUE));
        roundtripWithAbnormalExponent(new BigDecimal(new BigInteger("1" + "0".repeat(100)), Integer.MIN_VALUE));

        /* These Strings have an exponent > Integer.MAX_VALUE */
        roundtripWithAbnormalExponent("1.0E+2147483649");
        roundtripWithAbnormalExponent("-9.223372036854775808E+2147483666");
        roundtripWithAbnormalExponent("1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E+2147483748");

        // Roundtrip tests
        Random random = RandomFactory.getRandom();
        for (int i=0; i<100; i++) {
            int size = random.nextInt(100) + 1;
            BigInteger bi = new BigInteger(size, random);
            if (random.nextBoolean())
                bi = bi.negate();
            int decimalLength = bi.toString().length();
            int scale = random.nextInt(decimalLength);
            BigDecimal bd = new BigDecimal(bi, scale);
            String bdString = bd.toString();
            // System.err.println("bi" + bi.toString() + "\tscale " + scale);
            // System.err.println("bd string: " + bdString);
            BigDecimal bdDoppel = new BigDecimal(bdString);
            if (!bd.equals(bdDoppel)) {
                System.err.println("bd string: scale: " + bd.scale() +
                                   "\t" + bdString);
                System.err.println("bd doppel: scale: " + bdDoppel.scale() +
                                   "\t" + bdDoppel.toString());
                throw new RuntimeException("String constructor failure.");
            }
        }
    }

    private static void roundtripWithAbnormalExponent(BigDecimal bd) {
        if (!bd.equals(new BigDecimal(bd.toString()))) {
            throw new RuntimeException("Abnormal exponent roundtrip failure");
        }
    }

    private static void roundtripWithAbnormalExponent(String s) {
        if (!s.equals(new BigDecimal(s).toString())) {
            throw new RuntimeException("Abnormal exponent roundtrip failure");
        }
    }

    /*
     * Verify precision is set properly if the significand has
     * non-ASCII leading zeros.
     */
    private static void nonAsciiZeroTest() {
        String values[] = {
            "00004e5",
            "\u0660\u0660\u0660\u06604e5",
        };

        BigDecimal expected = new BigDecimal("4e5");

        for(String s : values) {
            BigDecimal tmp = new BigDecimal(s);
            // System.err.println("Testing " + s);
            if (! expected.equals(tmp) || tmp.precision() != 1) {
                System.err.println("Bad conversion of " + s + "got " +
                                   tmp + "precision = " + tmp.precision());
                throw new RuntimeException("String constructor failure.");
            }
        }

    }

    private static void leadingExponentZeroTest() {
        BigDecimal twelve = new BigDecimal("12");
        BigDecimal onePointTwo = new BigDecimal("1.2");

        String start = "1.2e0";
        String end = "1";
        String middle = "";

        // Test with more excess zeros than the largest number of
        // decimal digits needed to represent a long
        int limit  = ((int)Math.log10(Long.MAX_VALUE)) + 6;
        for(int i = 0; i < limit; i++, middle += "0") {
            String t1 = start + middle;
            String t2 = t1 + end;

            // System.out.println(i + "\t" + t1 + "\t" + t2);
            testString(t1, onePointTwo);
            testString(t2, twelve);
        }
    }

    private static void testString(String s, BigDecimal expected) {
        testString0(s, expected);
        testString0(switchZero(s), expected);
    }

    private static void testString0(String s, BigDecimal expected) {
        if (!expected.equals(new BigDecimal(s)))
            throw new RuntimeException(s + " is not equal to " + expected);
    }

    private static String switchZero(String s) {
        return s.replace('0', '\u0660'); // Arabic-Indic zero
    }

    private static void constructWithError(String badString) {
        try {
            BigDecimal d = new BigDecimal(badString);
            throw new RuntimeException(badString + " accepted");
        } catch(NumberFormatException e) {
        }
    }
}
