package org.teiid.query.sql.symbol;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.teiid.query.parser.ParseInfo;
import org.teiid.query.parser.SQLParser;
import org.teiid.query.sql.lang.Command;

import java.io.StringReader;
import java.math.BigDecimal;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

public class TestSelectFromNumber {

    @ParameterizedTest
    @CsvSource({
            "SELECT 3.0e+2, SELECT 300.0, 300.0",
            "SELECT 3.0e-2, SELECT 0.03, 0.03",
            "SELECT 3.0e2, SELECT 300.0, 300.0",
            "SELECT 3e+2, SELECT 300.0, 300.0",
            "SELECT 3e-2, SELECT 0.03, 0.03",
            "SELECT 3e2, SELECT 300.0, 300.0",
            "SELECT 3.0e+2 AS test_alias, SELECT 300.0 AS test_alias, 300.0",
            "SELECT 3.0e-2 AS test_alias, SELECT 0.03 AS test_alias, 0.03",
            "SELECT 3.0e2 AS test_alias, SELECT 300.0 AS test_alias, 300.0",
            "SELECT 3e+2 AS test_alias, SELECT 300.0 AS test_alias, 300.0",
            "SELECT 3e-2 AS test_alias, SELECT 0.03 AS test_alias, 0.03",
            "SELECT 3e2 AS test_alias, SELECT 300.0 AS test_alias, 300.0",
            "SELECT 1.23e-45, SELECT 1.23E-45, 0.00000000000000000000000000000000000000000000123",
            "SELECT 4.56e78, SELECT 4.56E78, 4560000000000000000000000000000000000000000000000000000000000000000000000000000",
            "SELECT -7.89e-10, SELECT -7.89E-10, -0.000000000789",
            "SELECT 9.99e+100, SELECT 9.99E100, 99900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
            "SELECT 1.0e0, SELECT 1.0, 1.0",
            "SELECT 2.0e1, SELECT 20.0, 20.0",
            "SELECT 3.0e-3, SELECT 0.003, 0.003",
            "SELECT 4.0e+4, SELECT 40000.0, 40000.0",
            "SELECT 5.0e+3, SELECT 5000.0, 5000.0",
            "SELECT 5.0e3, SELECT 5000.0, 5000.0",
            "SELECT 5e+3, SELECT 5000.0, 5000.0",
            "SELECT 5e-3, SELECT 0.005, 0.005",
            "SELECT 5e3, SELECT 5000.0, 5000.0",
            "SELECT 5.0e+4, SELECT 50000.0, 50000.0",
            "SELECT 5.0e4, SELECT 50000.0, 50000.0",
            "SELECT 5e+4, SELECT 50000.0, 50000.0",
            "SELECT 5e-4, SELECT 5.0E-4, 0.00050",
            "SELECT 5e4, SELECT 50000.0, 50000.0"
    })
    public void testExponentialNotation(String actual, String expected, String virtualityStudioLook) throws Exception {
        SQLParser parser = new SQLParser(new StringReader(actual));
        Command command = parser.command(new ParseInfo());
        assertNotNull(command);
        assertEquals(expected, command.toString());
        assertEquals(virtualityStudioLook, formatToVirtualityStudioLook(command));
    }

    @ParameterizedTest
    @CsvSource({
            "SELECT 33.333e-3, SELECT 0.033333, 0.033333",
            "SELECT 333.333e-3, SELECT 0.333333, 0.333333",
            "SELECT 3333.333e-3, SELECT 3.333333, 3.333333",
            "SELECT 33333.333e-3, SELECT 33.333333, 33.333333",
            "SELECT -10e9, SELECT -1.0E10, -10000000000",
            "SELECT 10e9, SELECT 1.0E10, 10000000000",
            "SELECT -10e-9, SELECT -1.0E-8, -0.000000010",
            "SELECT 10e-10, SELECT 1.0E-9, 0.0000000010",
            "SELECT 10e-11, SELECT 1.0E-10, 0.00000000010",
            "SELECT 31.415926535e-1, SELECT 3.1415926535, 3.1415926535",
            "SELECT 31415926535.0e-10, SELECT 3.1415926535, 3.1415926535",
            "SELECT 300.00e1, SELECT 3000.0, 3000.0",
            "SELECT 300.33e1, SELECT 3003.3, 3003.3",
            "SELECT 1914840686e1, SELECT 1.914840686E10, 19148406860",
            "SELECT 1914840687e1, SELECT 1.914840687E10, 19148406870",
            "SELECT 4914840687e1, SELECT 4.914840687E10, 49148406870"
    })
    public void testExponentialNotationNew(String actual, String expected, String virtualityStudioLook) throws Exception {
        SQLParser parser = new SQLParser(new StringReader(actual));
        Command command = parser.command(new ParseInfo());
        assertNotNull(command);
        assertEquals(expected, command.toString());
        assertEquals(virtualityStudioLook, formatToVirtualityStudioLook(command));
    }

    private static String formatToVirtualityStudioLook(Command command) {
        return new BigDecimal(Double.toString(Double.parseDouble(command.toString()
                .replace("SELECT", "")
                .replace(" AS test_alias", ""))))
                .toPlainString();
    }
}
